Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Self as associated type bound in protocol

I want to force an associated type to be Self, but the compiler is having none of it.
Here's what I want to get to compile:

protocol Protocol {
    // Error: Inheritance from non-protocol, non-class type 'Self'
    associatedtype Type: Self
}

You might ask, why not just use Self instead of an associated type? Simply because I cannot: the associated type is inherited from a parent protocol. And it doesn't make sense to change that in the parent protocol.
Here's something similar to what I'm trying to do:

protocol Factory {
    associatedtype Type

    func new() -> Type
}

protocol SelfFactory: Factory {
    associatedtype Type: Self // Same Error
}

Edit:
matt's answer is almost what I'm looking for. It behaves like I want it to at runtime, but is not restrictive enough at compile time.
I want this to be impossible:

protocol Factory {
    associatedtype MyType
    static func new() -> MyType
}

protocol SelfFactory: Factory {
    static func new() -> Self
}

final class Class: SelfFactory {

    // Implement SelfFactory:
    static func new() -> Class {
        return Class()
    }

    // But make the Factory implementation diverge:
    typealias MyType = Int

    static func new() -> Int {
        return 0
    }
}

I'd like the typealias in Class to trigger a redeclaration error or similar.

like image 372
ThinkChaos Avatar asked Feb 07 '23 07:02

ThinkChaos


2 Answers

I realize this is an old question, but you can do this as of Swift 4.0:

protocol Factory {
    associatedtype MyType
    static func new() -> MyType
}

protocol SelfFactory: Factory where MyType == Self { }

Aren't where clauses great?

like image 74
Michael Morris Avatar answered Feb 17 '23 06:02

Michael Morris


Are you trying to say this?

protocol Factory {
    associatedtype MyType
    func new() -> MyType
}

protocol SelfFactory: Factory {
    func new() -> Self
}
like image 28
matt Avatar answered Feb 17 '23 06:02

matt