首先,让我们解释的错误:
考虑:
class Foo<T:Hashable> { }
class SubFoo<String> : Foo<String> { }
这里的混乱的部分是,我们希望“字符串”是指雨燕定义的结构保持字符的集合。但事实并非如此。
在这里,“字符串”是我们给出新子类SubFoo
的泛型类型的名称。
class SubFoo<String> : Foo<T> { }
此行T
产生一个错误的使用了未经申报类型的:如果我们做出一些改变,这变得非常明显。
那么如果我们改变行这样:
class SubFoo<T> : Foo<T> { }
我们回到你原来有同样的错误,“T”不符合“哈希的”。在这里很明显,因为T并没有混淆现有Swift类型的名称,它恰好符合'Hashable'。很明显'T'是一个通用的。
当我们写'String'时,它也只是泛型类型的占位符名称,实际上并不是Swift中存在的String
类型。
如果我们要对特定类型的泛型类的不同的名称,相应的处理方法几乎可以肯定是一个typealias
:
class Foo<T:Hashable> {
}
typealias StringFoo = Foo<String>
这是完全有效的斯威夫特,并将其编译就好了。
相反,如果我们要的是真正继承并添加方法或属性的泛型类,那么我们需要的是一个类或协议,这将使我们的通用更具体的我们所需要的。
让我们回到最初的问题,让我们首先摆脱错误的:
class Foo<T: Hashable>
class SubFoo<T: Hashable> : Foo<T> { }
这是完全有效的斯威夫特。但它对我们正在做的事情可能并不特别有用。
,我们不能做以下的唯一原因:
class SubFoo<T: String> : Foo<T> { }
很简单,因为String
不是斯威夫特类 - 这是一个结构。这对于任何结构都是不允许的。
如果我们写了一个新的协议,从Hashable
继承,我们可以使用:
protocol MyProtocol : Hashable { }
class Foo<T: Hashable> { }
class SubFoo<T: MyProtocol> : Foo<T> { }
这是完全有效的。
另外请注意,我们实际上并不需要从Hashable
继承:
protocol MyProtocol { }
class Foo<T: Hashable> { }
class SubFoo<T: Hashable, MyProtocol> { }
这也是非常有效的。
但是请注意,无论出于何种原因,Swift都不会让你在这里使用类。例如:
class MyClass : Hashable { }
class Foo<T: Hashable> { }
class SubFoo<T: MyClass> : Foo<T> { }
斯威夫特神秘抱怨说“T”不符合“哈希的”(甚至当我们添加必要的代码来使其
最后,正确的。方法,最迅捷,合适的方法将被写入新的协议,从“哈希的”继承并添加你需要的任何功能它。
它不应该是严格重要的是,我们的子类接受String
。 wha应该很重要我们的子类需要它,它具有我们所需要的任何方法和属性。
不是这样。有关于此的Swift问题/限制,请参阅http://stackoverflow.com/questions/24138359/limitation-with-classes-derived-from-generic-classes-in-swift – Ixx
@lxx:Ick。我怀疑这仍然是*原因*,但你想要一个不同的解决方案。我用可能的解决方案编辑了我的答案,以供尝试。 –
嗯,是的,抛弃类型参数的解决方案有效,但我没有尝试它,因为它很丑。另一方面,我再次尝试使用typealias解决方案,它现在可以工作。有一个问题,因为(选择答案)它使用Int作为占位符,这就是为什么我尝试使用String,参数并导致错误。我用T取代了它,并且声明了类中的typealias,而不是它编译的。但它仍然是一种解决方法。谢谢反正我指回到正确的解决方案:) – Ixx