【发布时间】:2014-11-01 07:04:13
【问题描述】:
我一直在努力为枚举正确实施ForwardIndexType 协议,特别是处理结束情况(即没有后继的最后一项)。 Swift 语言书并没有真正涵盖这个协议。
这是一个简单的例子
enum ThreeWords : Int, ForwardIndexType {
case one=1, two, three
func successor() ->ThreeWords {
return ThreeWords(rawValue:self.rawValue + 1)!
}
}
successor() 函数将返回下一个枚举器值,除了最后一个元素,它将失败并出现异常,因为.three 之后没有值
ForwardTypeProtocol 不允许successor() 返回条件值,所以似乎没有办法表明没有后继者。
现在在 for 循环中使用它来迭代枚举的所有可能值的封闭范围,最终情况会遇到问题:
for word in ThreeWords.one...ThreeWords.three {
print(" \(word.rawValue)")
}
println()
//Crashes with the error:
fatal error: unexpectedly found nil while unwrapping an Optional value
在执行 for 循环中的语句之前,Swift 莫名其妙地调用了范围结束值的 successor() 函数。如果范围半开ThreeWords.one..<ThreeWords.three,则代码正确执行,打印1 2
如果我修改后继函数,使其不会像这样尝试创建大于.three 的值
func successor() ->ThreeWords {
if self == .three {
return .three
} else {
return ThreeWords(rawValue:self.rawValue + 1)!
}
}
那么 for 循环不会崩溃,但它也错过了最后一次迭代,打印的结果就像范围是半开一样1 2
我的结论是swift的for循环迭代有一个bug;它不应该在封闭范围的结束值上调用successor()。其次,ForwardIndexType 应该能够返回一个可选项,以便能够表示某个值没有后继。
有人在这个协议上取得了更大的成功吗?
【问题讨论】: