简体   繁体   中英

Swift protocol that is using an enum with generic associated type

I'm trying to create a protocol that is using a generic enum in swift. The compiler throws this error: Protocol can only be used as a generic constraint because it has associated type requirements

Short code snipped:

enum GenericEnum<T> {
    case Unassociated
    case Associated(T)
}

protocol AssociatedProtocol {
   typealias AssociatedType
   func foo() -> GenericEnum<AssociatedType>
}

let bar = [AssociatedProtocol]()

You can find a longer example here .

Does anybody know a solution to that issue?

Here's the problem: imagine some subsequent lines of code.

// none of this will compile...
var bar = [AssociatedProtocol]()
bar.append(GenericEnum.Associated(1))
bar.append(GenericEnum.Associated("hello")
let foo = bar[0].foo()

What type is foo ? Is it a GenericEnum<Int> or a GenericEnum<String> ? Or neither?

This is especially a problem because enums, like structs, are “value types”. That means their size is determined by what they contain. Take the following code:

let x = GenericEnum.Associated(1)
sizeofValue(x)  // 9 - 1 byte for the enum, 8 for the Int
let y = GenericEnum.Associated("hello")
sizeofValue(y)  // 25 - 1 byte for the enum, 24 for the String

Protocols with associated types are only really there to constrain generic functions. So this would be fine:

func f<T: AssociatedProtocol>(values: [T]) {
    var bar = [T]()  // T is an instance of a specific 
                     // AssociatedProtocol where T.AssociatedType
                     // is fixed to some specific type
}

but to use it stand-alone doesn't make sense (at least with the current version 1.2 of Swift – new features might enable other things in the version).

If you need the protocol to be used polymorphically dynamically at runtime, you would need to ditch the typealias. Then instead it can be used as a fixed-size reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM