user1178952
user1178952

Reputation:

In Swift, how do I write a protocol which exposes another generic protocol?

Something like this:

protocol MyCollection {
    var collection:Collection where Collection.Element == Int { get }
}

I want a ‘MyCollection’ type to expose a collection of Ints, where the actual type of collection is private. Only the methods in the Collection protocol are available on collection property.

Upvotes: 1

Views: 224

Answers (2)

matt
matt

Reputation: 535945

I want a ‘MyCollection’ type to expose a collection of Ints, where the actual type of collection is private

You can’t. You cannot use a generic protocol as a type (e.g. as the declared type of a variable or parameter). A generic protocol plain and simple is not a type.

The only place you can use a generic protocol plain and simple is as a constraint.

Upvotes: 1

dfrib
dfrib

Reputation: 73206

As of SE-0142: Permit where clauses to constrain associated types you can blueprint an associatedtype in you protocol and put constraints on it, thereafter blueprint the collection variable to be declared as the constrained associatedtype:

protocol MyCollection {
    associatedtype C : Collection where C.Element == Int
    var collection: C { get }
}

Examples:

// OK: C inferred as [Int] which fulfills the constraint on the associated type
struct Foo: MyCollection {
    var collection = [Int]()
}

// error: type 'Bar' does not conform to protocol 'MyCollection'
// note: protocol requires nested type 'C'; do you want to add it?
struct Bar: MyCollection {
    var collection = [Float]()
}

// error: 'MyCollection' requires the types 'Float' and 'Int' be equivalent
// note: requirement specified as 'Self.C.Element' == 'Int' [with Self = Baz]
struct Baz: MyCollection {
    typealias C = [Float]
    var collection: C = []
}

Upvotes: 1

Related Questions