1

I'm using Xcode 7.3 and Swift 2.3. I have difficulties using protocols with associated types that have variables. Look at the example:

protocol SomeProtocol {}
class SomeProtocolImpl: SomeProtocol {}

protocol ProtocolWithAssociatedType {
    associatedtype T: SomeProtocol

    var variable: T { get }
}

class TestClass: ProtocolWithAssociatedType {

    var variable: SomeProtocol = SomeProtocolImpl()

}

For some reason, compiler shows errors: error image How is that possible? Am I doing something wrong? Is it a bug? A known one?

What I've tried:

defined typealias for that associated type:

class TestClass: ProtocolWithAssociatedType {
    typealias O = SomeProtocol
    var variable: SomeProtocol = SomeProtocolImpl()
}

nope.

Used method instead:

protocol SomeProtocol {}
class SomeProtocolImpl: SomeProtocol {}

protocol ProtocolWithAssociatedType {
    associatedtype T: SomeProtocol

    func someMethod() -> T
}

class TestClass: ProtocolWithAssociatedType {
    typealias T = SomeProtocol

    func someMethod() -> SomeProtocol {
        return SomeProtocolImpl()
    }

}

just got different errors: second error image

How should I create protocol with associated type and variable and avoid this errors?

Fyodor Volchyok
  • 5,610
  • 4
  • 28
  • 45

1 Answers1

2

The compiler needs a specific type for T that conforms to SomeProtocol.

While this line looks correct

var variable: SomeProtocol

the problem the compiler is running into is that SomeProtocol is not a type, it's a protocol.

The easiest solution, tell the compiler a type to use

var variable: SomeProtocolImpl = SomeProtocolImpl()

or just let it figure it out itself.

var variable = SomeProtocolImpl()
Craig Siemens
  • 12,942
  • 1
  • 34
  • 51
  • Your explanation is right, but I still can't understand why `The compiler needs a specific type for T that conforms to SomeProtocol`. Is there any reason for it? Is it just a temporarily compile limitation? – Fyodor Volchyok Nov 02 '16 at 15:33
  • And unfortunately your answer doesn't solve my problem - I still need to declare this variable as a protocol to preserve incapsulation and avoid relying on concrete implementation. – Fyodor Volchyok Nov 02 '16 at 15:36
  • Then you'd have to change your protocol to not use an associated type. `var variable: SomeProtocol { get }` – Craig Siemens Nov 02 '16 at 15:42
  • solution with type erasure wrappers from http://stackoverflow.com/questions/37360114/unable-to-use-protocol-as-associatedtype-in-another-protocol-in-swift seems much more appropriate – Fyodor Volchyok Nov 03 '16 at 09:08