简体   繁体   中英

How can you initialize a struct with a closure parameter like this?

In this question I saw today It defines a struct Effect that has a property run that is a closure that takes a Generic parameter:

struct Effect<T> {
    let run: (@escaping (T) -> Void) -> Void
}

Then the sample code creates an instance of Effect<Int> , and specifies the closure for the run property with something that looks like trailing closure syntax:

let anIntInTwoSeconds = Effect<Int> { callback in
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        callback(42)
    }
}

What makes that legal? I would expect to need to specify the run parameter explicitly in a call to the init method:

let anIntInTwoSeconds = Effect<Int>(run: { callback in
    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        callback(42)
    }
}
)

Either version compiles and works. What in Swift makes that first version legal? I couldn't figure out how to frame the question so that I could search for an answer.

This works just like any function whose last parameter is a function. Trailing closure syntax is trailing closure syntax. The fact that the function is an initializer changes nothing.

So let me build up to it in stages. You know you can say:

func myfunc(whatever: () -> ()) {}
myfunc {}

Okay, but now let's make it a static method:

struct S {
    static func myfunc(whatever: () -> ()) {}
}
S.myfunc {}

OK, but init is a static method — it's just a static method whose name you are allowed to omit:

struct S {
    let whatever: () -> ()
}
S {} // meaning S.init {}

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