我试图使用泛型实现以下结构。得到一个奇怪的编译器错误,不能弄清楚为什么。
class Translator<T:Hashable> {...} class FooTranslator<String>:Translator<String> {...}
这个想法是,译者使用T作为字典中键的类型。这可以是例如。 a String或枚举。子类提供具体的字典。
但它失败,因为:“类型’字符串’不符合协议’Hashable’”
但String符合Hashable!我坚果吗?它也不适用于Int,也符合Hashable。它也不工作,如果我替换Hashable与Equatable,这也应该由两个实现。
如果我删除类型约束,只是为了测试(我还必须禁用字典,因为我不能使用任何不哈希的密钥) – 它编译
class Translator<T> {...} class FooTranslator<String>:Translator<String> {...}
我究竟做错了什么?
我不是一个Swift开发人员,但是在Java中遇到过类似的问题,我怀疑问题是,你现在声明一个类型参数叫String,因为你声明了类FooTranslator< String> – 因此,转换器< String>中的类型参数只是那个类型参数,它没有约束。你根本不想要一个类型参数,我怀疑(即你不希望你的FooTranslator是一个泛型类本身。)
如在评论中所指出的,在Swift subclasses of a generic class also have to be generic.你可以声明一个throw-away类型参数,如下所示:
class FooTranslator<T>:Translator<String>
这仍然避免声明一个新的类型参数称为String,这是什么导致的问题。这意味着你引入一个新的类型参数,当你不想要任何类型参数,但它可能比没有什么更好!
这是所有的假设,你真的需要一个子类,例如。添加或覆盖成员。另一方面,如果你只想要一个类型与Translator< String>完全相同,你应该使用一个类型别名:
typealias FooTranslator = Translator<String>
或者甚至混合两个在一个可怕的方式,如果你真的想要一个子类,但不想以一个通用的方式引用它:
class GenericFooTranslator<T>:Translator<String> typealias FooTranslator = GenericFooTranslator<Int>
(请注意,Int这里是故意不是String,以表明T在转换器中不同于FooTranslator中的T。)