Search code examples
swiftclosurescapture-list

Why does captured object reference to implicitly unwrapped variable have to be unwrapped?


In my project, trying to use capture lists with closures, but I have injected dependencies that are implicitly unwrapped since I guarantee that they will be populated by dependency injection. I discovered that using a capture list resulted in a compile error.

var forced: String!

func example() {
    escapingClosure { [forced] in
        let new = forced + "something" //has to be unwrapped again despite being forced
        print(new)
    }
}


func escapingClosure(closurce: @escaping () -> ()) {
    //do something
}

Here is the error:

enter image description here

I can resolve this by force unwrapping inside the closure, but I'm surprised that is necessary given the implicitly unwrapped declaration. Why is that step necessary? Is this a bug or a feature?


Solution

  • You can declare implicit unwrappedness, but you cannot propagate it. There is actually no such thing as an implicitly unwrapped Optional type, so when you pass or assign or capture a value declared as that type, it reverts to a normal Optional. For example:

     var forced: String! = "test"
     let x = forced
    

    You will find that x is an ordinary Optional, a String?. Your captured value is like that.