0

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
2
  • 2
    may be something like array.append(Bar() as T)? Commented Mar 8, 2016 at 4:21
  • Yes, casting to T fixed it. Somehow that solution totally alluded me haha. Thank you! Commented Mar 8, 2016 at 4:26

2 Answers 2

1

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)
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You've offered the same solution as @njzk2 (in the comments). But, you did elaborate with the example, so I suppose it's ok to mark this as correct... it does need to be forcibly cast, so thanks for pointing that out.
0

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())
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.