元素是可选的生成器如何知道它们何时到达终点?

时间:2016-03-27 22:02:27

标签: swift

Swift GeneratorType引用说明了next方法:

  

next()前进到下一个元素并返回它,如果没有下一个元素,则返回nil。

然后在讨论中,它说

  

要求:next()自复制完成后尚未应用于self的副本,并且之前没有self.next()的调用已返回nil。鼓励此协议的特定实施方式通过调用preconditionFailure("...")来响应违反此要求的行为。

如果Generator是可选类型,则它可能在到达序列末尾之前达到nil值。 Swift如何知道在这种情况下还没有达到目的?

1 个答案:

答案 0 :(得分:8)

重要的是要注意,无论生成器生成什么类型​​,它都会将该类型包装在一个可选项中。

GeneratorType协议声明了一个它调用Element的关联类型和一个方法next(),其返回类型的类型为Element?。无论Element是什么,next()都将它包装在一个可选项中(记住,可选的只是一个枚举)。

因此,生成选项的生成器将这些选项包装在另一个可选层中。

请考虑以下事项:

let array: [Int?] = [1, 2, nil, 4, nil, nil, 7, 8, nil, nil, 11]

这是一个可选整数数组。

因此,如果我们在此数组上调用generate(),它将为我们提供从Optional<Optional<Int>>方法返回Int??next()类型的内容。

enter image description here

next的前两次调用将为我们提供值(1,然后是2)。第三个看起来像是返回nil

enter image description here

但实际上这只是误导性的信息。实际上,第三个回报实际上就是这样:Optional.Some(nil)

我们可以看到,通过查看此while循环可以生成更多值,该循环由在11之后生成的 real nil终止:

enter image description here

我们看到打印的所有nil值实际上都是Optional.Some(nil),当next()调用最终返回Optional.None时,循环终止。

我们在这里看到的是以下三个值可能值之间的差异:

let optionalSomeValue: Int?? = 3
let optionalSomeNil: Int?? = Optional.Some(nil)
let optionalReallyNil: Int?? = nil

请注意,第二行也可以写为:

let optionalSomeNil: Int?? = Optional.Some(Optional.None)

在一天结束时,我们必须记住,optional是一个通用枚举:

enum Optional<T> {
    case Some(T)
    case None
}

T可以是什么没有限制,这意味着它本身可以是一个可选项,并且可以是None案例的可选项。

在Swift中,nil关键字只是Optional<T>.None的便捷快捷方式,而声明选项的?语法同样是Optional<T>.Some的便捷快捷方式。考虑以下两行除了变量名之外的每种方式都是等效的:

let foo = Optional<Int>.None
let bar: Int? = nil

enter image description here