通用类作为参数

时间:2015-02-05 14:58:15

标签: swift generics

我试图使用泛型来逃避大量的投射。我将提供一个简单的例子:

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实例......所以这并没有帮助。

我不知道为什么该示例使用默认的Swift Arrays:

import UIKit

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

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

虽然列表的类型为[String]而不是[AnyObject],但没有错误。我可以为我的泛型类获得相同的行为吗?

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

更新8/22/2016:正如@DeFrenZ在评论中指出的那样,我的示例依赖于集合作为引用类型。但是,在Swift中,集合是值类型。所以如果你可以编译我的例子,我不认为会有任何问题。变量listslists2是单独的集合。变异不会影响另一个。

原帖在下面继续:

除了上面的评论和我分享的链接http://nomothetis.svbtle.com/type-variance-in-swift(作者:Alexandros Salazar),还值得指出为什么集合的协方差(没有约束)通常不是类型安全的。

以下是一个例子:

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. 

(我是从内存中编写这种语法,并且在将变量分配给变量时不记得Swift的实际语义,但希望这可以指出问题。)