Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 什么';Swift枚举中泛型关联值的确切限制是什么?_Generics_Swift_Enums - Fatal编程技术网

Generics 什么';Swift枚举中泛型关联值的确切限制是什么?

Generics 什么';Swift枚举中泛型关联值的确切限制是什么?,generics,swift,enums,Generics,Swift,Enums,我试图理解Swift中具有泛型关联值的枚举的确切限制 您可能认为它们是受支持的,因为Optional就是这样一种类型。以下是Swift标准库中定义可选的代码: enum Optional<T> : Reflectable, NilLiteralConvertible { case None case Some(T) // ... } 遗憾的是,当前Swift编译器不支持泛型关联值 事实上,如果您在编译器中键入该代码段,您会得到一个错误(错误:未实现的IR生成功能非固

我试图理解Swift中具有泛型关联值的枚举的确切限制

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

enum Optional<T> : Reflectable, NilLiteralConvertible {
    case None
    case Some(T)
// ...
}
遗憾的是,当前Swift编译器不支持泛型关联值

事实上,如果您在编译器中键入该代码段,您会得到一个错误(
错误:未实现的IR生成功能非固定多负载枚举布局

这是怎么回事?是否只是一般不支持它,而是作为特例支持
Optional
?有没有办法了解Optional是如何获得这种特殊支持的?或者如果其他标准库类型也得到特殊支持?

此答案在Swift 2中已过时。有关Swift 2更新,请参见rickster的答案

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

典型的解决方案是创建一个额外的包装器类来保存泛型类型,就像FP book所做的那样。按照惯例,每个人都称它为
Box
。我们有理由希望Swift团队将来能够解决这个问题。正如您所注意到的,他们将其称为“未实现”而不是“不支持”

Box
的典型实现:

final public class Box<T> {
  public let unbox: T
  public init(_ value: T) { self.unbox = value }
}
最终公共类框{
公共租赁:T
public init(value:T){self.unbox=value}
}
在Swift 2中(作为Xcode 7的一部分),对相关值没有限制。所以,可以自由地随着这样的节拍跳舞:

enum YouCanGoWith<T, U> {
    case This(T)
    case That(U)
    case Us
}
…如果您的函数成功,则调用方始终会为walken获取一个(非可选)
位置
。与使用结果不同,调用方决定如何处理、接受或传播错误

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


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

似乎只有当关联的泛型值是唯一关联的值时,关联的泛型值才是可能的。哦,对了。因此,在错误中,“多有效载荷”指的是存在不止一个关联值。那么“非固定”呢?我猜这是因为
T
的大小是不确定的,因为如果它是非类类型,那么就不能确定它是否有对象指针的大小。我在游乐场的经验是,它们并不总是给出正确的编译器错误。因此,一些看似可以编译的东西并不意味着它实际上可以工作。你必须在最后添加一些附加值,并确保它确实显示了一个值,以证明操场正在运行。当你使编译器崩溃时(这种事情仍然经常发生),这一点就更加正确了。正因为如此,我几乎总是在小的命令行应用程序中做不平凡的工作(阅读:一切)。但失败和成功运行测试用例是完全不同的。为了避免混淆,暂时取消了该部分。遗憾的是,尽管编译器允许您以这种方式声明枚举,但它不允许您将其绑定到switch语句中;我在
开关结果{case let.Success(data):…}
上尝试了许多变体,所有这些变体都失败了,出现了有用的(/s)警告“Command…/bin/swiftc failed with exit code 1”。没有进一步的编译器警告指示模式匹配的哪一部分导致编译器中止。编译器无法在崩溃时发出警告。根据swift编程语言手册,抛出的
关键字必须在箭头之前。示例应该是:
func walkWith(节奏:Bool)抛出->放置{/*…*/}
enum YouCanGoWith<T, U> {
    case This(T)
    case That(U)
    case Us
}
func walkWith(rhythm: Bool) throws -> Place { /* ... */ }