一尘不染

为什么泛型不编译?

swift

我正在尝试使用泛型实现以下结构。收到编译器错误,无法找出原因。

class Translator<T:Hashable> {...}

class FooTranslator<String>:Translator<String> {...}

这个想法是译者使用T作为字典中键的类型。例如,可以是字符串或枚举。子类提供具体的字典。

但是它失败,因为:“类型’String’不符合协议’Hashable’”

但是String符合Hashable。它也不适用于Int,后者也符合Hashable。

如果删除类型约束,则仅用于测试(在此我还必须禁用字典,因为我不能在其中使用任何不可哈希的键)-它会编译

class Translator<T> {...}

class FooTranslator<String>:Translator<String> {...}

我究竟做错了什么?


阅读 183

收藏
2020-07-07

共1个答案

一尘不染

我不是开发商斯威夫特,但是看在Java中类似的问题,我怀疑的问题是,此刻的你正在声明称为类型参数String,因为你宣告classFooTranslator<String>-这样的类型 参数_的Translator<String>就是这种类型的参数,没有任何限制。你不
_希望
在所有类型参数,我怀疑(即你不希望你FooTranslator成为一个通用类本身)。

如注释中所述,在通用类的子类中,也必须是通用类。您可以声明一个抛弃型参数,如下所示:

class FooTranslator<T>:Translator<String>

仍然避免声明一个名为的新类型参数String,而这正是导致此问题的原因。这意味着你要介绍的,当你不新类型参数
任何类型的参数,但它可能是聊胜于无…

所有这些都基于您确实需要一个子类的假设,例如添加或覆盖成员。另一方面,如果您只想要与 完全相同
的类型Translator<String>,则应改用类型别名:

typealias FooTranslator = Translator<String>

甚至甚至以可怕的方式将两者混合使用,如果您确实想要一个子类但又不想以一种通用的方式引用它:

class GenericFooTranslator<T>:Translator<String>
typealias FooTranslator = GenericFooTranslator<Int>

(注意,Int这里是故意不String,以表明TTranslator不一样TFooTranslator)。

2020-07-07