Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.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
Swift 实现枚举ForwardIndexType_Swift_Enums - Fatal编程技术网

Swift 实现枚举ForwardIndexType

Swift 实现枚举ForwardIndexType,swift,enums,Swift,Enums,我一直在努力为枚举正确地实现ForwardIndexType协议,特别是在处理结束情况(即最后一项没有后续项)时。Swift语言手册并未真正涵盖该协议 下面是一个简单的例子 enum ThreeWords : Int, ForwardIndexType { case one=1, two, three func successor() ->ThreeWords { return ThreeWords(rawValue:self.rawValue +

我一直在努力为枚举正确地实现
ForwardIndexType
协议,特别是在处理结束情况(即最后一项没有后续项)时。Swift语言手册并未真正涵盖该协议

下面是一个简单的例子

enum ThreeWords : Int, ForwardIndexType {
    case one=1, two, three

    func successor() ->ThreeWords {
            return ThreeWords(rawValue:self.rawValue + 1)!
    }
}
succession()
函数将返回下一个枚举数值,但最后一个元素除外,该元素将因异常而失败,因为
之后没有值。三个

ForwardTypeProtocol
不允许
succession()
返回条件值,因此似乎无法发出没有后继者的信号

现在,在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莫名其妙地调用范围结束值的
succession()
函数。如果范围半开
ThreeWords.one..实际上,似乎最后一个值将调用
后续值

enum ThreeWords : Int, ForwardIndexType {
    case one=1, two, three
    case EXHAUST

    func successor() ->ThreeWords {
        return ThreeWords(rawValue:self.rawValue + 1) ?? ThreeWords.EXHAUST
    }
}


您可能希望这样做,但为了解决这个问题,您可以简单地添加一个sentinel值作为后续值。

似乎,
..
操作符

func ...<Pos : ForwardIndexType>(minimum: Pos, maximum: Pos) -> Range<Pos>
因此,如果要将
enum
用作
Range.Index
,则必须定义最后一个值的下一个

enum ThreeWords : Int, ForwardIndexType {
    case one=1, two, three
    case EXHAUST

    func successor() ->ThreeWords {
        return ThreeWords(rawValue:self.rawValue + 1) ?? ThreeWords.EXHAUST
    }
}

这是一个老问题,但我想总结一些事情,并发布另一个可能的解决方案


正如@jtbandes和@rintaro已经声明的那样,用
start…end
操作符创建的闭合范围是用
start.在内部创建的,这很糟糕,因为现在我所有的enum switch语句都感染了一个必需的默认情况
enum ThreeWords : Int, ForwardIndexType {
    case one=1, two, three
    case EXHAUST

    func successor() ->ThreeWords {
        return ThreeWords(rawValue:self.rawValue + 1) ?? ThreeWords.EXHAUST
    }
}
for word in ThreeWords.one...ThreeWords.three {...}
var interval:ClosedInterval = ThreeWords.one...ThreeWords.four
enum ThreeWords : Int, ForwardIndexType, Comparable {
    case one=1, two, three, four

    func successor() ->ThreeWords {
        return ThreeWords(rawValue:self.rawValue + 1)!
    }
}
func <<T: RawRepresentable where T.RawValue: Comparable>(lhs: T, rhs: T) -> Bool {
    return lhs.rawValue < rhs.rawValue
}
var interval:ClosedInterval = ThreeWords.one...ThreeWords.four
switch(ThreeWords.four) {
    case ThreeWords.one...ThreeWords.two:
        print("contains one or two")
    case let word where interval ~= word:
        print("contains: \(word) with raw value: \(word.rawValue)")
    default:
        print("no case")
}