本文介绍了奇怪的泛型错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用泛型来实现以下结构。得到一个奇怪的编译器错误,无法找出原因。

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

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

这个想法是Translator使用T作为字典中的一个键的类型。这可以是例如一个字符串或枚举。 Subclass提供了具体的字典。



但是它因此失败:Type'String'不符合协议'Hashable'



但字符串符合Hashable!我疯了吗?它也不适用于Int,它也符合Hashable。如果我用Equatable替换Hashable,它也是行不通的,应该由两者来实现。



如果我删除类型约束,仅用于测试(我也是必须禁用字典,因为我不能使用任何不可散列的键作为键) - 它编译

  class Translator< T> ; {...} 

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

我做错了什么?

class FooTranslator< String> - 所以类型参数放在 Translator< String> 就是那个没有约束的类型参数。你根本不需要一个类型参数,我怀疑(即你不希望你的 FooTranslator 是一个泛型类本身。)

正如评论中指出的,在Swift中。您可以声明一个抛弃类型参数,如下所示:

  class FooTranslator< T>:Translator< String> 

它仍然避免声明一个新的类型参数 String 任何类型参数时,你会引入一个新的类型参数,但它可能比没有任何其他类型的参数...



这一切都假设你确实需要一个子类,例如添加或覆盖成员。另一方面,如果您只是想要一个类型与 Translator< String> 完全相同,则应该使用类型别名:

  typealias FooTranslator = Translator< String> 

或者甚至以可怕的方式混合两者,如果您真的想要一个子类但不想要必须以通用的方式引用它:

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

(请注意,这里的 Int 是故意的而不是字符串,以显示 Translator 中的 T isn与 FooTranslator 中的 T 相同。)


I'm trying to implement following structure using generics. Getting a weird compiler error, can't figure out why.

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

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

The idea is that Translator uses T as the type of a key in a dictionary. This can be e.g. a String or an enum. Subclass provides concrete dictionary.

But it fails because of this: "Type 'String' does not conform to protocol 'Hashable'"

But String conforms to Hashable! Am I nuts? It also doesn't work with Int, which also conforms to Hashable. It also doesn't work if I replace Hashable with Equatable, which should be also implemented by both.

If I remove the type constraint, just for testing (where I also have to disable the dictionary, as I can't use anything not hashable as key there) - it compiles

class Translator<T> {...}

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

What am I doing wrong?

解决方案

I'm not a Swift developer, but having seen similar problems in Java, I suspect the problem is that at the moment you're declaring a type parameter called String because you're declaring class FooTranslator<String> - so the type argument in Translator<String> is just that type parameter, which has no constraints. You don't want a type parameter at all, I suspect (i.e. you don't want your FooTranslator to be a generic class itself.)

As noted in comments, in Swift subclasses of a generic class also have to be generic. You could possibly declare a throw-away type parameter, like this:

class FooTranslator<T>:Translator<String>

which still avoids declaring a new type parameter called String, which was what was causing the problem. It means you're introducing a new type parameter when you don't want any type parameters, but it's possibly better than nothing...

This is all on the assumption that you really need a subclass, e.g. to add or override members. On the other hand, if you just want a type which is exactly the same as Translator<String>, you should use a type alias instead:

typealias FooTranslator = Translator<String>

Or even mix the two in a horrible way, if you genuinely want a subclass but don't want to have to refer to it in a generic way:

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

(Note that the Int here is deliberately not String, to show that the T in Translator isn't the same as the T in FooTranslator.)

这篇关于奇怪的泛型错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 22:03