Reputation: 92409
I have a class called Controller that contains one Array property. Right now, my class is declared like that:
class Controller {
var myArray: [AnyObject]
init(bool: Bool) {
if bool == true {
myArray = [10, 11, 12]
} else {
myArray = ["Yo", "Ya", "Yi"]
}
}
}
The problem that I have with this code is that myArray is still (of course) of type [AnyObject] after my class initialization. Thus, every time I need to get an object out of myArray, I have to cast its type (Int or String) just like this:
let controller = Controller(bool: false)
let str = controller.array[0] as String
I want to be able to write let str = controller.array[0] //str: String
without having to cast the real type of the objects inside myArray. Is there a way to do so? Do I have to use lazy init, struct, generic types?
Here is a attempt in pseudo code:
class Controller {
var myArray: Array<T> //Error: use of undeclared type 'T'
init(bool: Bool) {
if bool == true {
myArray = [10, 11, 12] as [Int] //myArray: Array<Int>
} else {
myArray = ["Yo", "Ya", "Yi"] as [String] //myArray: Array<String>
}
}
}
Upvotes: 0
Views: 91
Reputation: 21003
So as Oscar and Elijah pointed out (up votes to them), I am just trying to be a little more verbose here. You need to declare the generic, T
, when you define the class.
This would mean you need to define what that generic's type is at initialization of the class.
class Foo<T> {
var items = [T]()
}
let stringFoo = Foo<String>()
stringFoo.items.append("bar")
stringFoo.items[0] = "barbar"
stringFoo.items // ["barbar"]
let intFoo = Foo<Int>()
intFoo.items.append(1)
intFoo.items[0] = 11
intFoo.items // [11]
So in your case, rather than passing a Bool
for the init
method, just define the generic's type at initialization instead.
Upvotes: 3
Reputation: 65
class Controller<T> //You missed that T, right?
{
var myArray: Array<T>
/* initialization stuff */
}
var c = Controller<String>()
c.myArray[0] = "Hey!"
let str = c.myArray[0] //String, eventually!
Upvotes: 3