使用泛型关联类型的enum的Swift协议



我试图创建一个在swift中使用通用enum的协议。编译器抛出以下错误: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]()

你可以在这里找到一个更长的例子。

有谁知道这个问题的解决办法吗?

问题是这样的:想象一些后续的代码行。

// 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版本-新功能可能会在版本中启用其他功能)。

如果您需要在运行时以多态动态方式使用协议,则需要放弃类型别名。然后,它可以用作固定大小的引用。

相关内容

  • 没有找到相关文章

最新更新