以下示例基于snippet,它生成的函数允许逐个枚举序列值。
此处printAreEqual ()
提供 true ,print2 ()
提供 12345678910 ,但print1 ()
提供 0000000000 。
为什么枚举返回的函数不能返回使用yield生成的序列的值?
open System.Linq
let enumerate (xs: seq<_>) =
use en = xs.GetEnumerator()
fun () ->
en.MoveNext() |> ignore
en.Current
let s1 = seq { for i in 1 .. 10 do yield i }
let s2 = seq { 1 .. 10 }
let f1 = s1 |> enumerate
let f2 = s2 |> enumerate
let printAreEqual () = Enumerable.SequenceEqual (s1, s2) |> printf "%b" // true
let print1 () = for i in 1 .. 10 do f1() |> printf "%i" // 0000000000
let print2 () = for i in 1 .. 10 do f2() |> printf "%i" // 12345678910
答案 0 :(得分:7)
use en = ...
函数中的enumerate
实际上是这样做的:
let enumerate (xs: seq<_>) =
let en = xs.GetEnumerator()
let f =
fun () ->
en.MoveNext() |> ignore
en.Current
en.Dispose()
f
在开始使用枚举器之前,你总是处理它,所以在这种情况下行为可能是不确定的,并且为什么你得到两个具有不同实现的序列的不同结果并不重要。
对序列枚举的细粒度控制总是很棘手,并且由于可变状态而难以制作辅助函数。