Weird escaping function behavior after updating to

2019-07-14 11:11发布

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?

标签: swift swift3
1条回答
干净又极端
2楼-- · 2019-07-14 12:00

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.

查看更多
登录 后发表回答