简体   繁体   中英

Reference to array inside function in Swift

I am trying to reference to an array inside a function.
Something like this: a and b are arrays of Int s.

  var inout refArr = &a
  if(!someFlag) {
     refArr = &b
  }
  refArr[someIndex] = 30

This does not compile, can I only use inout for function arguments? If so, how do I do a reference/pointer inside a function?

& can only be used to pass a variable as an inout argument to a function. So the easiest solution is perhaps to use a helper function inside your function:

func foo() {

    func helper(inout array : [Int]) {
        array[2] = 99
    }

    var a = [1, 2, 3, 5, 6]
    var b = [4, 5, 6, 7]
    let someFlag = true

    if someFlag {
        helper(&a)
    } else {
        helper(&b)
    }

    // ...
}

You can create a reference to the array using UnsafeMutableBufferPointer :

let ref = someFlag ?
    UnsafeMutableBufferPointer(start: &a, count: a.count) :
    UnsafeMutableBufferPointer(start: &b, count: b.count)
ref[2] = 99

But there are two problems with this solution:

  • UnsafeMutableBufferPointer() creates a non-owning reference, so the compiler might decide to deallocate the array while the reference is still used.
  • There is no bounds check on the array.

So to make this work safely, you have to add some code:

withExtendedLifetime(a) { () -> Void in
    withExtendedLifetime(b) { () -> Void in
        let ref = someFlag ?
            UnsafeMutableBufferPointer(start: &a, count: a.count) :
            UnsafeMutableBufferPointer(start: &b, count: b.count)
        if ref.count > 2 {
            ref[2] = 99
        }
    }
}

which is a bit ugly.

You can use inout parameters in your function to accomplish this. Use the inout modifier for your parameters and use the ampersand (&) when passing a value into the function like so:

func swapTwoInts(inout a: Int, inout b: Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var x = 5
var y = 10

swapTwoInts(&x, &y)

x // 10
y // 5

Arrays in swift are not guaranteed to be contiguous in memory the way they are in C, so to insure you have access to a contiguous block, you have to either pass them to a function with an inout parameter or--if you really want a reference to an array within the function--create an UnsafeMutableBufferPointer like this[1]:

var someFlag: Bool = false
var a = ["a", "b", "c"]
var b = ["d", "e", "f"]

var refArr = a.withUnsafeMutableBufferPointer { (inout output: UnsafeMutableBufferPointer<String>) -> UnsafeMutableBufferPointer<String> in

    return output
}

println(refArr[1]) //Will Output 'a'

if !someFlag {
    refArr = b.withUnsafeMutableBufferPointer { (inout output: UnsafeMutableBufferPointer<String>) -> UnsafeMutableBufferPointer<String> in

        return output
    }
}

println(refArr[1]) //Will Output 'e'

1. Thread Safety with Swift Arrays

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM