Jan B
Jan B

Reputation: 1

How to constraint an accociatedtype to be an protocol

How do I constraint an accociatedtype to be an protocol.

Lets say I have the following protocol and a class implementing it:

public protocol TestProtocol {
    associatedtype TestType
}

public class TestClass<T : NSCoding>  : TestProtocol {

    public typealias TestType = T

    public func get<T>(_ identifier: String) throws -> T? {
        return "Test" as? T
    }
}

Now everything is fine. func get will compile because the compiler knows that my accociated type is an protocol in that case.

The problem starts with this use case:

public protocol TestProtocol {
    associatedtype TestType

    func get<T>(_ identifier: String) throws -> T? where T : TestType
}

public class TestClass<T : NSCoding>  : TestProtocol {

    public typealias TestType = T

    public func get<T>(_ identifier: String) throws -> T? {
        return "Test" as? T
    }
}

this will not compile since the compiler doesn't know if TestType is an ProtocolType in this case.

(it says: "Type 'T' constrained to non-protocol type 'TestType'")

How can I enforce the accociated type 'TestType' in the Protocol to be a protocol type ?

edit: My first example is a bit misleading a better definition of what I want to achieve is the following

public protocol TestProtocol {
    associatedtype TestType

    func get<T>(_ identifier: String) throws -> U? where U : TestType
}

public class TestClass<T : NSCoding>  : TestProtocol {

    public typealias TestType = T

    public func get<U>(_ identifier: String) throws -> U? where U : T{
        return "Test" as? U
    }
}

I want the return type of 'get' to be of type U and implement the protocol T (I want to use it to retrieve data from my persistence store).

The problem ist that this notation doesn't enforce that T is a protocol type (Which results in the compiler error). How could I enforce that ?

second edit:

The longer I look at the problem, the more I'm shure that Swift-Proposal SE-0142 is the solution to this problem (and a swift 4 feature).

https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md

But if you have other ideas how to achieve the needed behaviour just let me know ;)

Upvotes: 0

Views: 95

Answers (1)

Alain T.
Alain T.

Reputation: 42133

As sbarow suggested :

public protocol TestProtocol {

    associatedtype TestType:Protocol

    func get<TestType>(_ identifier: String) throws -> TestType? 
}

Upvotes: 0

Related Questions