为什么泛型不编译? [英] Why generics don't compile?

查看:69
本文介绍了为什么泛型不编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

这个想法是翻译器使用T作为字典中键的类型.例如字符串或枚举.子类提供具体的字典.

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.

但是它失败了,因为:类型'String'不符合协议'Hashable'"

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

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

But String conforms to Hashable. It also doesn't work with Int, which also conforms to Hashable.

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

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> {...}

我在做什么错了?

推荐答案

我不是Swift开发人员,但是在Java中看到过类似的问题后,我怀疑问题在于,您现在正在声明一个名为String因为您要声明class FooTranslator<String>-所以Translator<String>中的 argument 类型就是该类型参数,没有任何约束.我怀疑您根本不想要类型参数(即您不希望您的FooTranslator本身成为泛型类).

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.)

如注释中所述,在Swift的通用子类中类也必须是通用的.您可以声明一个抛弃型参数,像这样:

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>

仍然避免声明一个称为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...

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

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>

(请注意,此处的Int故意不是String,以显示Translator中的TFooTranslator中的T不同.)

(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.)

这篇关于为什么泛型不编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆