swift - 如何在 Swift 的泛型扩展中使用带有可选类方法的协议(protocol)?

标签 swift generics swift-extensions swift-protocols

我正在尝试使用类方法对现有类使用扩展,例如:

@objc public protocol MyProtocol {
    optional class func foo() -> Int
}

我在扩展中使用这个协议(protocol),像这样:

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”。如果我不在协议(protocol)中使用“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)。我的猜测是泛型的实现目前没有考虑到可选类级函数的可能性。

你可以不用像这样的泛型来做到这一点:

func f(p: MyProtocol) {
    (p as AnyObject).dynamicType.foo?()
}

(甚至可能有更好的方法,但我找不到)。

您需要 AnyObject 转换,因为如果您尝试在 p 上直接调用 .dynamicType.foo?(),您会得到“访问成员协议(protocol)类型值 'MyProtocol.Type' 未实现”。如果通用版本的崩溃与此有关,我不会感到惊讶。

我还要说,值得问问自己是否真的需要一个带有可选方法(尤其是类级方法)的协议(protocol),以及是否有一种方法可以完全静态地使用泛型来做你想做的事情(因为你已经半-做)。

关于swift - 如何在 Swift 的泛型扩展中使用带有可选类方法的协议(protocol)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27779473/

相关文章:

swift - 如何更改 UICollectionView 滚动方向?

ios - 身份验证后在 iOS 中使用 DynamoDB

java - 在运行时获取列表对象的类型

swift - Swift 3.0 中浮点元素数组的扩展

ios - 请参阅 swift stdout 以获取 react native 应用程序

swift - 二元运算符 '&=' 不能应用于 Swift 中的两个 'Bool' 操作数

javascript - Typescript 推断高阶函数的类型,该函数执行具有相同参数签名的可选函数参数

java - 实现通用接口(interface)时如何避免强制转换

ios - 使用扩展来扩展多个类

ios - 将类型传递给通用 Swift 扩展,或者理想地推断它