首先,讓我們解釋的錯誤:
考慮:
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