以下代码使快速(3,3.1,4)编译器崩溃:
protocol Test { func f() } let x = Test.f // crash
我可能天真地希望编译器将其推断x为具有签名的Function Type (Test) -> (Void) -> Void,之后,我可以这样称呼它:
x
(Test) -> (Void) -> Void
let y = SomeClassConformingToTest() x(y)()
我想我的问题是:显然,编译器应该执行除崩溃以外的其他操作,但是Swift目前应该支持这种语法吗?
如您所说,编译器永远不会崩溃;这确实是一个错误,已在此处提交。Swift团队成员Slava Pestov在其中说:
我们计划使MyProtocol.someInstanceMethod工作。您已经可以在课程中执行此操作,例如, class Foo { func f() { ... } } let f: Foo -> () -> () = Foo.f 它对于协议应该具有相同的行为: protocol Foo { func f() } let f: Foo -> () -> () = Foo.f 我计划稍后再解决。
我们计划使MyProtocol.someInstanceMethod工作。您已经可以在课程中执行此操作,例如,
class Foo { func f() { ... } } let f: Foo -> () -> () = Foo.f
它对于协议应该具有相同的行为:
protocol Foo { func f() } let f: Foo -> () -> () = Foo.f
我计划稍后再解决。
到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"