这段代码使 swift (3, 3.1, 4) 编译器崩溃:
protocol Test {
func f()
}
let x = Test.f // crash
我可能天真地希望编译器将 x
推断为具有签名 (Test) -> (Void) -> Void
的函数类型,并且稍后,我可以这样调用它:
let y = SomeClassConformingToTest()
x(y)()
我想我的问题是:显然编译器应该做一些不同于崩溃的事情,但是 Swift 目前应该支持这种语法吗?
最佳答案
正如您所说,编译器永远不应该崩溃;这确实是一个错误,has been filed here .在其中,Swift 团队的成员 Slava Pestov 说:
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.
截至 2017 年 5 月 8 日,错误报告现在被标记为“进行中”,因此希望它能进入 Swift 4.0 的发布版本。
但是,在实现/修复之前——一个简单的解决方法是使用闭包表达式作为方法的部分应用的 thunk 来调用它:
protocol Test {
func f()
}
struct S : Test {
func f() {
print("hello")
}
}
let x: (Test) -> () -> Void = { $0.f }
let s = S()
x(s)() // "hello"
当然,如果你不需要中间部分应用函数,你可以说:
let x: (Test) -> Void = { $0.f() }
let s = S()
x(s) // "hello"
关于swift - 从 swift 协议(protocol)中存储/传递函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45176965/