问题
I'm having difficulties with the following lines of code after updating to Swift 3:
private var functionHandlers = [(() -> Int) -> ()]()
private var myFunction: (() -> Int)?
func doRegister() {
functionHandlers.append { (f: (() -> Int)) in
myFunction = f
}
}
That gave me the compiler error: Assigning non-escaping parameter 'f' to an escaping closure
So then, I tried this:
func doRegister() {
functionHandlers.append { (f: @escaping (() -> Int)) in
myFunction = f
}
}
and this:
func doRegister() {
functionHandlers.append { (f: (@escaping () -> Int)) in
myFunction = f
}
}
which, in both cases, fixed my first error, but then gave me a new compiler error: Cannot convert value of type '(@escaping (() -> Int)) -> ()' to expected argument type '(() -> Int) -> ()'
So then I tried changing the type of functionHandlers as follows:
private var functionHandlers = [(@escaping (() -> Int)) -> ()]()
but that just resulted in a syntax error.
Can anyone explain to me why this is happening and what I can do to fix this?
回答1:
Looks like a bug to me. For some reason, the compiler doesn't like the syntax:
private var functionHandlers = [(@escaping () -> Int) -> ()]()
but it does like:
private var functionHandlers : [(@escaping () -> Int) -> ()] = []
It's the same symptom, but I'm unsure it's the same cause as the compiler rejecting the [TypeA.TypeB]() syntax with nested types. Although like that problem, another way of solving it is by using a typealias:
typealias F = (@escaping () -> Int) -> ()
private var functionHandlers = [F]()
You can then implement doRegister() as you correctly tried to implement it as:
func doRegister() {
functionHandlers.append { (f: @escaping () -> Int) in
myFunction = f
}
}
Although you should certainly file a bug report over [(@escaping () -> Int) -> ()]() not compiling.
来源:https://stackoverflow.com/questions/40599881/weird-escaping-function-behavior-after-updating-to-swift-3