dh0rmfpdlxm
dh0rmfpdlxm

Reputation: 321

swift protocol associatedtype

I have a question about swift protocol associated type.

protocol SomeProtocol {}

protocol TestAProtocol: SomeProtocol {}

protocol TestBProtocol: SomeProtocol {}

class TestA: TestAProtocol {}

class TestB: TestBProtocol {}

protocol Service {
    associatedtype S: SomeProtocol

    var service: S? { get }
}

class ServiceModule: Service {
    var service: TestAProtocol?
}

this code has an error because service's type in ServiceModule is a protocol(TestAProtocol)(not concrete type).

class ServiceModule: Service {
    var service: TestA?
}

or

class ServiceModule: Service {
    var service: TestB?
}

it's ok.

but I want to have a variable that conforms protocol(ex. TestAProtocol) that conforms specific protocol(ex. SomeProtocol).

like this:

class ServiceModule: Service {
        var service: TestAProtocol? // or var service: TestBProtocol?
    }

is it possible?

Upvotes: 0

Views: 66

Answers (1)

Louis Lac
Louis Lac

Reputation: 6406

This does not work because you did no specified the associated type in your ServiceModule class and Swift compiler cannot infer the underlying type. You should use your protocol as a generic constraint instead:

class ServiceModule<P: TestAProtocol>: Service {
    var service: P?
}

Here P is a concrete type conforming to TestAProtocol which will be resolved at compile time. The caller (class init) will define the associated type. Here P will be of type TestA.

let instance = ServiceModule<TestA>()

The most important to understand is that you cannot use a protocol with an associated type as a concrete type. You can only:

  • Use it a a generic constraint
  • use the some keyword (only for functions and computed properties) to return an opaque type bidding the implementation.

Upvotes: 3

Related Questions