Storing/passing Function Types from swift protocols

萝らか妹 提交于 2019-11-27 08:45:10

问题


This bit of code crashes the swift (3, 3.1, 4) compiler:

protocol Test {
    func f()
}
let x = Test.f // crash

I would expect, perhaps naively, that the compiler would infer x as a Function Type with the signature (Test) -> (Void) -> Void, and that later on, I could call it like so:

let y = SomeClassConformingToTest()
x(y)()

I guess my question is: clearly the compiler should do something other than crash, but should Swift currently support this syntax?


回答1:


As you say, the compiler should never crash; this is indeed a bug, and has been filed here. In it, Slava Pestov, a member of the Swift team, says:

We plan on making MyProtocol.someInstanceMethod work. You can already do this for classes, eg,

class Foo {
    func f() { ... }
}
let f: Foo -> () -> () = Foo.f

It should have the same behavior for protocols:

protocol Foo {
    func f()
}
let f: Foo -> () -> () = Foo.f

I plan on addressing this later.

And the bug report, as of the 8th of May 2017, is now marked as "In Progress", so hopefully this is something that will make it into the release build of Swift 4.0.

However, until implemented/fixed – a simple workaround is just to use a closure expression in order to act as a thunk for the partial application of the method with the instance to call it on:

protocol Test {
    func f()
}

struct S : Test {
    func f() {
        print("hello")
    }
}

let x: (Test) -> () -> Void = { $0.f }

let s = S()
x(s)() // "hello"

and of course, if you don't need the intermediate partially applied function, you can just say:

let x: (Test) -> Void = { $0.f() }

let s = S()
x(s) // "hello"


来源:https://stackoverflow.com/questions/44589459/storing-passing-function-types-from-swift-protocols

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!