当在协议扩展中实现返回 Self
的静态协议函数时,在扩展中实现该函数会出现错误(最简化的场景,不带上下文):
import Foundation
protocol P {
static func f() -> Self
static func g() -> Self
}
extension P {
static func f() -> Self { // Method 'f()' in non-final class 'NSData' must return `Self` to conform to protocol 'P'
return g()
}
}
extension NSData: P {
static func g() -> Self {
return self.init()
}
}
将错误行中的Self
替换为P
会导致编译器出现段错误(sig 11)(这似乎是传达类型不匹配错误的有效方式)。
将f()
的声明更改为返回P
,并在错误行上用P
替换Self
会导致成功编译,但会失去类型精度(并且需要在每个调用点进行强制向下转换,还需要详细记录Self
的要求)。
是否有其他解决此问题的方法,而不会失去通用返回类型?
编辑:进一步提供上下文信息: P
是一个公共协议,将由库公开,用于各种类型遵循(并覆盖g()
),因此在NSData
中重写f()
不是一个选项。还最好不必将f()
更改为除协议扩展之外的其他内容,因为它在库内部的许多地方都被使用。考虑到这两个选项,将f()
的返回类型更改为P
是一个更好的选择。
更新
从Swift 4(可能是3)开始,上述代码可以正常工作。