Reputation: 3780
I have a protocol named Foo
and a struct named Bar
. Bar
conforms to Foo
.
protocol Foo {}
struct Bar: Foo {}
Appending a Bar
instance to an array of Bar
works as expected.
var array = [Bar]()
array.append(Bar())
Now, I have a generic struct called Baz
that's initialized with a type that conforms to Foo
(e.g. Bar
).
struct Baz<T: Foo> {
private(set) var array = [T]()
init() {
if T.self is Bar.Type {
// Error: Cannot invoke 'append' with an argument list of type (Bar)
array.append(Bar())
}
}
}
Attempting to append to the array results in the following error:
Cannot invoke 'append' with an argument list of type (Bar)
Why doesn't this work as expected?
As an aside, the use case is something like this:
let bazBarStack = Baz<Bar>().array
let bazQuxStack = Baz<Qux>().array
Upvotes: 0
Views: 1458
Reputation: 9044
You need to store objects in array, that are of type T. Therefore you should cast using as! T
:
struct Baz<T: Foo> {
private(set) var array = [T]()
init() {
if T.self is Bar.Type {
array.append(Bar() as! T)
}
}
}
Upvotes: 1
Reputation: 13750
Because array
holds elements of a single type T
, which must conform to Foo
but is not necessarily compatible with Bar
. It looks like you wish to have an array that can hold anything conforming to Foo
; in this case, get rid of the generics altogether and simply write
private(set) var array = [Foo]()
and then your init will be
init() {
array.append(Bar())
}
Upvotes: 0