Variable capture by closures in Swift and inout parameters

cfischer

I noticed that when a variable is captured by a closure in Swift, the closure can actually modify the value. This seems crazy to me and an excellent way of getting horrendous bugs, specially when the same var is captured by several closures.

var capture = "Hello captured"
func g(){
    // this shouldn't be possible!
    capture = capture + "!"
}

g()
capture

On the other hand, there's the inout parameters, which allow a function or closure to modify its parameters.

What's the need for inout, even captured variables can already be modified with impunity??!!

Just trying to understand the design decisions behind this...

Aaron Rasmussen

David's answer is totally correct, but I thought I'd give an example how capture actually works as well:

func captureMe() -> (String) -> () {

    //  v~~~ This will get 'captured' by the closure that is returned:
    var capturedString = "captured"

    return {

        // The closure that is returned will print the old value,
        // assign a new value to 'capturedString', and then 
        // print the new value as well:

        println("Old value: \(capturedString)")
        capturedString = $0
        println("New value: \(capturedString)")
    }
}

let test1 = captureMe()      // Output: Old value: captured
println(test1("altered"))    //         New value: altered

// But each new time that 'captureMe()' is called, a new instance
// of 'capturedString' is created with the same initial value:

let test2 = captureMe()               // Output: Old value: captured
println(test2("altered again..."))    //         New value: altered again...

// Old value will always start out as "captured" for every 
// new function that captureMe() returns. 

The upshot of that is that you don't have to worry about the closure altering the captured value - yes, it can alter it, but only for that particular instance of the returned closure. All other instances of the returned closure will get their own, independent copy of the captured value that they, and only they, can alter.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Swift 4: Escaping closures can only capture inout parameters explicitly by value

Swift 3.0 Error: Escaping closures can only capture inout parameters explicitly by value

Swift closure capture and inout variables

parameters with optional closures in swift

Swift optional inout parameters and nil

Is swift inout parameter a variable or a pointer?

Swift 2.0 'inout' function parameters and computed properties

Correct placement of capture list in nested closures in swift

Swift, how much of "self" do closures capture?

swift affect value to inout generic variable

How to denote mutable parameters in closures with Swift > 2.2?

passing multiple closures as parameters to a function in swift

Swift/iOS: How to use inout parameters in functions with AnyObject/Any or Pointers

Is there any difference between "mutating" function and "inout" parameters in Swift?

Is it possible to create an array of functions that take "inout" parameters in Swift?

Is it possible to point class instance variables to `inout` parameters in Swift?

Assigning value to inout parameters within closure in Swift 3

Swift How to DRY code in variable closures?

Why Swift global functions as a special case of closures capture global variables?

When to use inout parameters?

IN, OUT, INOUT Parameters

Is it possible to capture a variable number of parameters in a lambda?

inout parameter in Swift

Inout in swift and reference type

"in" vs "inout" in Swift

What's Objective-C's equivalent of Swift's inout Parameters?

Variable Number of Parameters in Swift Method

Inout argument in nested function in Swift

Behaviour of inout within Swift operators