swift - 从 swift 协议(protocol)中存储/传递函数类型

标签 swift swift-protocols

这段代码使 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/

相关文章:

swift - `override` 在协议(protocol)中是什么意思?

swift - 将不透明类型与关联类型一起使用

swift - 获取 CGFloat 类型的第一个数字

ios - 获取结果 Controller 中没有单元格的空部分(标题 View )

swift - 常量序列可以使用for-in循环迭代,但不能直接调用next()?

swift - 使核心数据类成为最终类以满足协议(protocol) 'Self' 要求

ios - 删除Eureka中单行的分隔线

ios - 使用 SwiftUI 中断后恢复 AVPlayer

ios - 在 Action 中更改同一 Tableview 单元格中的不同按钮(Swift)

swift - 为什么是 'there cannot be more than one conformance, even with different conditional bounds' ?