【问题标题】:Swift protocol that is using an enum with generic associated type使用具有通用关联类型的枚举的 Swift 协议
【发布时间】:2015-05-27 12:47:24
【问题描述】:

我正在尝试创建一个在 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

有人知道这个问题的解决方案吗?

【问题讨论】:

  • AssociatedType 的别名是什么?

标签: swift generics enums protocols


【解决方案1】:

这就是问题所在:想象一些后续代码行。

// 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&lt;Int&gt; 还是GenericEnum&lt;String&gt;?还是两者都没有?

这尤其是一个问题,因为枚举和结构一样,都是“值类型”。这意味着它们的大小取决于它们所包含的内容。取以下代码:

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 1.2。
猜你喜欢
  • 2018-01-31
  • 2020-05-24
  • 1970-01-01
  • 1970-01-01
  • 2019-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
相关资源
最近更新 更多