2

Is there any way to use array of protocol's generic? For example,

/* I want to use protocol like below, 
 * but I can't because protocol is not concrete 
 * so cannot make array of it */
class MyClass<T where T:MyProtocol, T:[MyProtocol]> {
    let result: T
}

protocol MyProtocol {
    init(with: String)
}

class SpecialThing: MyProtocol {
    let appleWatch: AppleWatch

    init(with: String) {
        self.appleWatch = AppleWatch(with)
    }
}

class SampleClass {
    func test {
        typealias listCallback = (MyClass<[SpecialThing]>, NSError) -> ()
        typealias oneCallback = (MyClass<SpecialThing>, NSError) -> ()
    }
}

There can be one object or array of protocol's subclass. I think "typealias" does not help me.

I want to find something more simple way.....

4
  • I don't think it is possible to have the generic type T specified as MyProtocol and array of MyProtocol at the same time. Commented Mar 29, 2016 at 13:52
  • I think so. I want to initialize generic object in MyClass. Researched everything but still cannot find solution. Commented Mar 29, 2016 at 14:11
  • Not possible far as I know. Pretty obvious but the only "solution" I know is class MyClass<T where T:MyProtocol> { let result: [T] } Commented Mar 29, 2016 at 14:28
  • @WillGlück I already solved my problem as exactly what you said. Just I was wondering there is another better way to do this. Thanks anyway! Commented Mar 30, 2016 at 2:20

2 Answers 2

1

My first issue with this is that the type signature is wrong:

class MyClass<T where T:MyProtocol, T:[MyProtocol]>

That's the same type of thing as doing:

let t: String
let t: [String]
t = String("foo")

The compiler will complain because you are redefining T, once as a MyProtocol and again as an array of MyProtocol. You can't have both, you can only have one.

Sign up to request clarification or add additional context in comments.

Comments

0

Answer: Use a construct like Either:

enum Either<T, U>
{
    case Left(T)
    case Right(U)

    var leftValue: T?
    {
        if case .Left(let leftValue) = self
        {
            return leftValue
        }

        return nil
    }

    var rightValue: U?
    {
        if case .Right(let rightValue) = self
        {
            return rightValue
        }

        return nil
    }
} 

Allowing for:

class MyClass<T: MyProtocol>
{
    let result: Either<T, [MyProtocol]>
}

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.