swift - 为什么这个 Swift 代码不进行类型检查?

标签 swift generics type-inference

以下 Swift 代码:

class Workflow<ItemClass: Hashable> {
    var block: (ItemClass -> Int)?
    init() {}
}

protocol ProtocolX {
    typealias ItemClass
    func foo(x: ItemClass) -> Int
}

func test<Y: ProtocolX, ItemClass: Hashable>(protX: Y, x: ItemClass) {
    let workflow = Workflow<ItemClass>()
    workflow.block = { (x: ItemClass) in
        return protX.foo(x)
    }
}

因以下编译器错误而失败:

Cannot invoke 'foo' with an argument list of type '(ItemClass)': 
Expected an argument list of type '(Self.ItemClass)'

在代码片段中返回protX.foo(x)

这可能看起来像是一个人为的例子,但它是从我遇到的现实世界问题中简化出来的。

如果我尝试遵循错误消息中的建议,我只会得到:

'Self' is only available in a protocol or as the result of a method in a class; 
did you mean 'Test'?

如何对其进行类型检查?

最佳答案

您没有让编译器相信 Workflow.ItemClass 与函数 test(_:x:) 中的 ProtocolX.ItemClass 类型相同。如果您的意思是要求 test 函数的 ItemClass 类型参数与函数内的 ProtocolX.ItemClass 相同,您可以告诉编译器需要它,如下所示:

func test<Y: ProtocolX, ItemClass: Hashable where Y.ItemClass == ItemClass>(protX: Y, x: ItemClass) {
    let workflow = Workflow<ItemClass>()
    workflow.block = { (x: ItemClass) in
        return protX.foo(x)
    }
}

但是您可以完全消除单独的 ItemClass 参数:

func test<Y: ProtocolX where Y.ItemClass: Hashable>(protX: Y, x: Y.ItemClass) {
    let workflow = Workflow<Y.ItemClass>()
    workflow.block = { (x: Y.ItemClass) in
        return protX.foo(x)
    }
}

关于swift - 为什么这个 Swift 代码不进行类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35234473/

相关文章:

generics - 如何使用涉及泛型的匿名类型调用泛型方法?

C# 类型推断 ("var") 从 '??' 空合并运算符赋值

swift - 将 scenekit 和 spritekit 组合在一个屏幕中

Java 泛型 - 不在界限之内

java - 通用 JUnit 测试

scala - 为什么 Scala 不能推断路径依赖类型的路径——即使是从显式的自引用中也是如此?

ios - 如何滚动到 UITextView 的顶部?

ios - Swift 应用程序在 iPad 上返回空白屏幕?

ios - Swift:如何无延迟地刷新 tableview (UIRefreshControl)

java - 方法参数必须是实现某个接口(interface)的某个类的obj