我试图使用泛型来逃避大量的投射。我将提供一个简单的例子:
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],但没有错误。我可以为我的泛型类获得相同的行为吗?
非常感谢您的帮助!
答案 0 :(得分:4)
更新8/22/2016:正如@DeFrenZ在评论中指出的那样,我的示例依赖于集合作为引用类型。但是,在Swift中,集合是值类型。所以如果你可以编译我的例子,我不认为会有任何问题。变量lists
和lists2
是单独的集合。变异不会影响另一个。
原帖在下面继续:
除了上面的评论和我分享的链接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的实际语义,但希望这可以指出问题。)