其實你沒有足夠強調。定義:
class Human {}
class Child: Human {}
struct Holder<T> {}
我做了一個支架結構,所以沒有人可以指責我們欺騙:數組是一個結構,持有人是一個結構。我取消了對佔位符的限制,將所有內容都縮小爲最簡單的形式。
現在只需指定兒童的數組,其中人類的陣列預計:
var arr = Array<Human>()
arr = Array<Child>()
精細。現在,隨着持有人嘗試:
var holder = Holder<Human>()
holder = Holder<Child>() // error
的並行現在看起來完美:數組是一個結構,持有人是一個結構,而我們正在做的是想多態分配。所以有什麼問題?
正如您可能已經懷疑的那樣,問題在於您不是Apple。 Apple編寫代碼,因此他們可以在參數化類型上定義Array和類似covariant。但它不是該語言的自動功能 - 也就是說,對於泛型,一般並非如此。並且特別是你不會那樣做你定義。
所以Apple的數組是協變的,但是你的Holder(或Person)不是,並且沒有什麼能讓你切換協方差。
你可以看到爲什麼數組是協變的。這是一個非常特殊的情況。數組是對象的集合。 Apple知道一個例如Child對象的數組實際上也是一個Human對象的數組,因爲每個Child都是一個Human(多態)。所以他們已經實現了數組的協方差,以確保這一點。
但是對於您的人或我的持有人沒有這樣的保證。 Swift不知道你打算如何用佔位符T做什麼。您可以考慮使用Holder<Child>
代替Holder<Human>
的情況,這可能是錯誤。所以蘋果公司在這方面不做任何假設。
我要補充,這區分下列事項:
class Human {}
class Child: Human {}
struct Holder<T> {
let thing : T
}
let holder : Holder<Human> = Holder(thing:Child()) // fine
這是合法的,但它沒有任何關係與我們一直在談論。這裏只涉及一種泛型:Holder<Human>
。我們正在做的是將一個孩子分配到thing
,其中一個人是預期的。這是非常老式的非泛型多態。但你仍然無法投出Holder<Human>
下降到Holder<Child>
,即使thing
是一個孩子,你仍然無法分配Holder<Child>
其中Holder<Human>
預期。
並且看到這個關於這個話題的經典文章:http://nomothetis.svbtle.com/type-variance-in-swift – matt