如何在 Swift 的泛型扩展中使用带有可选 class 方法的协议?
How to use a protocol with optional class methods in an extension with generic in Swift?
我正在尝试使用 class 方法对现有 class 使用扩展,例如:
@objc public protocol MyProtocol {
optional class func foo() -> Int
}
我在扩展中使用这个协议,像这样:
extension MyClass {
public func bar<T: MyProtocol>() {
...
let x: Int = T.self.foo!() // if I do not use "self" or "!" here, I will have a compiler error
...
}
这应该可以,但是当我构建它时,Xcode 说 "Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1"。如果我不在协议中使用 "optional",我就不需要在扩展中解包 foo(),即使我删除 "self" 也一切正常。谁能告诉我为什么以及如何使可选功能正常工作?
提前致谢。
您似乎在 Swift 编译器中发现了一个(相当模糊的)错误,该错误导致它崩溃。
这是一个复制品,您需要在一个文件中崩溃 swiftc
:
import Foundation
@objc protocol P { optional class func f() }
func f<T: P>(t: T) { T.self.f?() }
(你不需要调用 f
它就会崩溃)
您可能应该提交雷达,因为无论您的代码如何,编译器崩溃都不是预期的行为。
如果您尝试在没有 optional
的情况下执行此操作,它会起作用(您甚至可以放弃 self
)。我的猜测是泛型的实现目前没有考虑可选 class 级函数的可能性。
你可以不用像这样的泛型来做到这一点:
func f(p: MyProtocol) {
(p as AnyObject).dynamicType.foo?()
}
(甚至可能有更好的方法,但我找不到)。
您需要 AnyObject
转换,因为如果您尝试在 p
上直接调用 .dynamicType.foo?()
,您会得到 "accessing members of protocol type value 'MyProtocol.Type' is unimplemented"。如果通用版本的崩溃与此有关,我不会感到惊讶。
我还要说,值得问问自己是否真的需要一个带有可选方法(尤其是 class 级别的方法)的协议,以及是否有一种方法可以使用泛型完全静态地做你想做的事情(因为你已经在半做)。
我正在尝试使用 class 方法对现有 class 使用扩展,例如:
@objc public protocol MyProtocol {
optional class func foo() -> Int
}
我在扩展中使用这个协议,像这样:
extension MyClass {
public func bar<T: MyProtocol>() {
...
let x: Int = T.self.foo!() // if I do not use "self" or "!" here, I will have a compiler error
...
}
这应该可以,但是当我构建它时,Xcode 说 "Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1"。如果我不在协议中使用 "optional",我就不需要在扩展中解包 foo(),即使我删除 "self" 也一切正常。谁能告诉我为什么以及如何使可选功能正常工作? 提前致谢。
您似乎在 Swift 编译器中发现了一个(相当模糊的)错误,该错误导致它崩溃。
这是一个复制品,您需要在一个文件中崩溃 swiftc
:
import Foundation
@objc protocol P { optional class func f() }
func f<T: P>(t: T) { T.self.f?() }
(你不需要调用 f
它就会崩溃)
您可能应该提交雷达,因为无论您的代码如何,编译器崩溃都不是预期的行为。
如果您尝试在没有 optional
的情况下执行此操作,它会起作用(您甚至可以放弃 self
)。我的猜测是泛型的实现目前没有考虑可选 class 级函数的可能性。
你可以不用像这样的泛型来做到这一点:
func f(p: MyProtocol) {
(p as AnyObject).dynamicType.foo?()
}
(甚至可能有更好的方法,但我找不到)。
您需要 AnyObject
转换,因为如果您尝试在 p
上直接调用 .dynamicType.foo?()
,您会得到 "accessing members of protocol type value 'MyProtocol.Type' is unimplemented"。如果通用版本的崩溃与此有关,我不会感到惊讶。
我还要说,值得问问自己是否真的需要一个带有可选方法(尤其是 class 级别的方法)的协议,以及是否有一种方法可以使用泛型完全静态地做你想做的事情(因为你已经在半做)。