Swift 使用具有通用关联类型的枚举的协议
Swift protocol that is using an enum with generic associated type
我正在尝试创建一个在 swift 中使用通用枚举的协议。
编译器抛出此错误:Protocol can only be used as a generic constraint because it has associated type requirements
截取的短代码:
enum GenericEnum<T> {
case Unassociated
case Associated(T)
}
protocol AssociatedProtocol {
typealias AssociatedType
func foo() -> GenericEnum<AssociatedType>
}
let bar = [AssociatedProtocol]()
您可以找到更长的示例 here。
有人知道这个问题的解决方案吗?
问题来了:想象一下后续的代码行。
// none of this will compile...
var bar = [AssociatedProtocol]()
bar.append(GenericEnum.Associated(1))
bar.append(GenericEnum.Associated("hello")
let foo = bar[0].foo()
foo
是什么类型?是 GenericEnum<Int>
还是 GenericEnum<String>
?或者两者都不是?
这尤其是个问题,因为枚举和结构一样,都是“值类型”。这意味着它们的大小取决于它们包含的内容。取以下代码:
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
具有关联类型的协议只是真正用于约束泛型函数。这样就可以了:
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
}
但是单独使用它没有意义(至少对于 Swift 的当前 1.2 版是这样——新功能可能会启用该版本中的其他功能)。
如果您需要在运行时以多态方式动态使用协议,则需要放弃类型别名。然后它可以用作固定大小的参考。
我正在尝试创建一个在 swift 中使用通用枚举的协议。
编译器抛出此错误:Protocol can only be used as a generic constraint because it has associated type requirements
截取的短代码:
enum GenericEnum<T> {
case Unassociated
case Associated(T)
}
protocol AssociatedProtocol {
typealias AssociatedType
func foo() -> GenericEnum<AssociatedType>
}
let bar = [AssociatedProtocol]()
您可以找到更长的示例 here。
有人知道这个问题的解决方案吗?
问题来了:想象一下后续的代码行。
// none of this will compile...
var bar = [AssociatedProtocol]()
bar.append(GenericEnum.Associated(1))
bar.append(GenericEnum.Associated("hello")
let foo = bar[0].foo()
foo
是什么类型?是 GenericEnum<Int>
还是 GenericEnum<String>
?或者两者都不是?
这尤其是个问题,因为枚举和结构一样,都是“值类型”。这意味着它们的大小取决于它们包含的内容。取以下代码:
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
具有关联类型的协议只是真正用于约束泛型函数。这样就可以了:
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
}
但是单独使用它没有意义(至少对于 Swift 的当前 1.2 版是这样——新功能可能会启用该版本中的其他功能)。
如果您需要在运行时以多态方式动态使用协议,则需要放弃类型别名。然后它可以用作固定大小的参考。