2015-02-05 59 views
3

我試圖使用泛型逃脫大量的鑄造。我會提供一個簡單的例子:通用類作爲參數

import UIKit 

class List<T> { 
    let items: [T] 

    init(items: [T]) { 
     self.items = items 
    } 
} 

class ListsViewController: UIViewController { 
    var lists: [List<AnyObject>] = [] 
} 

let viewController = ListsViewController() 
let lists = [List(items: ["Fruits"])] 
viewController.lists = lists 
        ^error "String" is not identical to "AnyObject" 

我讀過,我可以做

class ListsViewController<T>: UIViewController 

,但比我會進一步出現問題倒在那裏我有救ListsViewController情況中,鏈...所以這並沒有幫助。

什麼爲什麼的例子使用默認斯威夫特陣列工作,我不明白這裏:

import UIKit 

class ListsViewController: UIViewController { 
    var lists: [AnyObject] = [] 
} 

let viewController = ListsViewController() 
let lists = ["Fruits", "Meat"] 
viewController.lists = lists 

沒有錯誤雖然列出的類型爲[字符串]不是[AnyObject。我可以爲我的泛型類獲得相同的行爲嗎?

非常感謝您的幫助!

+1

這裏有一篇關於逆變和協變的文章,可能會有所幫助。 http://nomothetis.svbtle.com/type-variance-in-swift許多語言允許數組是協變的(儘管它不是類型安全的並且需要運行時檢查)。然而,這種「寬大」並不總是適用於你發現的所有課程。 C#有同樣的問題(直到它添加了一種安全的方式來實現協方差) – 2015-02-05 15:05:28

+0

這裏是我發佈的鏈接中的一個簡短的相關段落「所有這些說,我們可以開發者聲明類型是協變,逆變還是不變嗎?不是我能看到的,到目前爲止,默認情況是內置的差異規則起作用(數組和字典協變,函數是......不管它們是什麼等),但是自定義類型都是不變的。「 – 2015-02-05 15:07:58

+0

我看,太糟糕了:( 感謝您整理出來! – warly 2015-02-05 15:18:20

回答

4

更新8/22/2016:正如@DeFrenZ在評論中指出的,我的例子依賴於集合是引用類型。但是,在Swift中,集合是值類型。所以如果你可以編譯我的例子,我不認爲會有任何問題。變量listslists2是單獨的集合。突變一個不會影響另一個。

原帖繼續下面:

除了上面我的意見,我也跟http://nomothetis.svbtle.com/type-variance-in-swift的鏈接(由亞歷山德羅·薩拉薩爾)爲什麼收藏的協方差(沒有限制),一般不是類型安全這是值得指出的。

下面是一個例子:(我在寫從內存這句法和分配集合變量的時候不記得斯威夫特的實際語義,但希望這點出了問題)

var lists: [List<AnyObject>] = [] 
var lists2: [List<String>] = List(items: ["Fruits"]) 
lists = lists2   // lists is now an alias for lists2 and is a reference to a list of strings 
lists.append(MyObject()) // Now I just put a MyObject into a list of strings 
var str:String = lists2[1] // assuming the previous lines compiled and ran ok, this would be a problem because lists2[1] is a MyObject. 

+3

這真的很重要。這裏的失敗並不是Swift缺乏功能,而是你要求的是不正確的。需要做的是在'ListsViewController'上添加一個類型參數,所以你有'lists:[T]'而不是'lists:[AnyObject]'幾乎任何時候你發現自己在一個屬性中使用'AnyObject',你可能做一些不正確的事情,你應該深入研究爲什麼這會給保存帶來麻煩,這可能是可以解決的問題 – 2015-02-05 16:49:22

+0

好的@RobNapier,可能比我對協助他的問題的評論更重要 – 2015-02-05 16:52:06

+0

謝謝你所有的解釋。 ,考慮後我會重構我的類,畢竟不使用AnyObject。我不是語言專家,但在我看來,仍然應該允許將定義的超類的子類放入集合中,然後從這裏繼續。在你的例子中,「lists」會變成[List ],所以lists.append(MyObject())將失敗。但這只是我:) – warly 2015-02-05 21:44:33