Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return an inout (reference) in a swift function?

I'd like a function to return a reference of an array:

var a = [1, 2]
var b = [3, 4]

func arrayToPick(i:Int) -> [Int] {
    return i == 0 ? a : b
}

inout var d = arrayToPick(0)
d[0] = 6

println(a[0]) // 1
println(d[0]) // 6

I'm unable to return &a or &b in arrayToPick because those can't be casted to [Int].

How to return a reference on a or b from a function?

like image 306
ldiqual Avatar asked Dec 18 '14 05:12

ldiqual


People also ask

How do you Inout in Swift?

Swift inout parameter is a parameter that can be changed inside the function where it's passed into. To accept inout parameters, use the inout keyword in front of an argument. To pass a variable as an inout parameter, use the & operator in front of the parameter.

What does Inout mean in Swift?

All parameters passed into a Swift function are constants, so you can't change them. If you want, you can pass in one or more parameters as inout , which means they can be changed inside your function, and those changes reflect in the original value outside the function.

How can I return multiple values from a function in Swift?

Tuples can be used to return multiple values from Swift functions. A tuple allows you to group together multiple values of different types which can then be returned from a function as a single entity.


1 Answers

You cannot return inout value. Because the compiler cannot guarantee the lifetime of the value.

You have unsafe way, like this:

var a = [1, 2]
var b = [3, 4]

func arrayToPick(i:Int) -> UnsafeMutablePointer<[Int]> {
    if i == 0 {
        return withUnsafeMutablePointer(&a, { $0 })
    }
    else {
        return withUnsafeMutablePointer(&b, { $0 })
    }
}

var d = arrayToPick(0)
d.memory[0] = 6

println(a[0]) // -> 6

In this case, after a is deallocated, d.memory access may cause BAD_ACCESS error.

Or safe way, like this:

var a = [1, 2]
var b = [3, 4]

func withPickedArray(i:Int, f:(inout [Int]) -> Void) {
    i == 0 ? f(&a) : f(&b)
}

withPickedArray(0) { (inout picked:[Int]) in
    picked[0] = 6
}

println(a[0]) // -> 6

In this case, you can access the picked value only in the closure.

like image 115
rintaro Avatar answered Sep 22 '22 14:09

rintaro