繁体   English   中英

Swift枚举中通用关联值的确切限制是什么?

[英]What's the exact limitation on generic associated values in Swift enums?

我试图理解Swift中具有通用关联值的枚举的确切限制。

您可能认为它们受支持,因为Optional是这样的类型。 以下是在Swift标准库中定义Optional的代码:

enum Optional<T> : Reflectable, NilLiteralConvertible {
    case None
    case Some(T)
// ...
}

看起来像case成员Some有一个变量类型T的关联值,对吗?

但是, 在Swift中的函数编程 (第87页)一书中提到,不支持这样的类型:

我们想在与Success相关的结果中定义一个通用的新枚举:

  枚举结果<T> {\n     案例成功(T)\n     案例失败(NSError) \n } 

遗憾的是,当前的Swift编译器不支持通用关联值。

事实上,如果您将该片段输入编译器,则会出现错误( error: unimplemented IR generation feature non-fixed multi-payload enum layout )。

那么这里发生了什么? 它只是一般不支持,但作为特殊情况支持Optional吗? 有没有办法看看Optional如何获得这种特殊支持? 或者,如果其他标准库类型也获得特殊支持?

在Swift 2中(作为Xcode 7的一部分),对关联值没有限制。 所以,随意跳舞,像这样的节拍:

enum YouCanGoWith<T, U> {
    case This(T)
    case That(U)
    case Us
}

现在,如果您正在寻找成功或错误类型的枚举,您可能想停下来思考为什么......因为Swift 2还带来了一个新的错误处理模型。 所以你不需要像函数的返回值这样的类型 - 你可以像这样声明它:

func walkWith(rhythm: Bool) throws -> Place { /* ... */ }

...如果你成功之后,主叫方总是得到一个(非可选) Place用于向沃肯。 并且 - 与使用结果分开 - 调用者决定如何处理,吞下或传播错误。

有关详细信息,请参阅Swift编程语言 错误处理 仔细观察 - 语法看起来有点像你在其他一些语言中看到的异常模型,但Swift错误是一种完全不同的动物。

(当然, throws模型特定于同步调用。如果你要声明异步进程的回调,回调闭包接收成功异步工作或错误的结果 - 成功或错误类型仍然完全适当。)

这个答案在Swift 2中已经过时了。请参阅rickster对Swift 2更新的回答。

你的意见是对的。 如果其中任何一个具有未知大小,则不能有多个具有关联数据的案例。 值类型可以是任何大小(因为它们被复制)。 引用类型(如对象)具有已知大小,因为它们存储指针。

对此的典型解决方案是创建一个额外的包装类来保存泛型类型,就像FP书一样。 按惯例,每个人都称之为Box 有理由希望Swift团队将在未来解决这个问题。 如您所知,他们将其称为“未实现”而非“不受支持”。

Box的典型实现:

final public class Box<T> {
  public let unbox: T
  public init(_ value: T) { self.unbox = value }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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