I was trying to use generics to get away with a lot of casting. I will provide a simple example:
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"
I've read that i could do
class ListsViewController<T>: UIViewController
but than i would have the problem further down the chain where i have to save ListsViewController instances...so that doesn't help.
What i don't get here why does the example work with the default Swift Arrays:
import UIKit
class ListsViewController: UIViewController {
var lists: [AnyObject] = []
}
let viewController = ListsViewController()
let lists = ["Fruits", "Meat"]
viewController.lists = lists
No error although lists is of type [String] not [AnyObject]. Can i get the same behaviour for my generic class as well?
Thanks so much for your help in advance!
Update 8/22/2016: As @DeFrenZ pointed out in the comments, my example relies on collections being reference types. However, in Swift, collections are value types. So if you could compile my example, I don't think there would be any issues. The variables lists and lists2 are separate collections. Mutating one will not affect the other.
Original post continues below:
In addition to my comments above and the link I shared http://nomothetis.svbtle.com/type-variance-in-swift (by Alexandros Salazar) it's worth pointing out why covariance of collections (with no constraints) is generally not type safe.
Here's an example:
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.
(I'm writing this syntax from memory and don't recall Swift's actual semantics when assigning collections to variables, but hopefully this points out the issue.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With