Mil*_*oDC 4 ienumerator f# seq
为什么在F#中,我可以这样做......
let s = seq { for i in 0 .. 4095 do yield i } :?> IEnumerator
Run Code Online (Sandbox Code Playgroud)
......但这会抛出一个System.InvalidCastException?
let s = Seq.init 4095 (fun i -> i) :?> IEnumerator
Run Code Online (Sandbox Code Playgroud)
序列表达式创建一个实现IEnumerable<T>和的对象 IEnumerator<T>
let s = seq { for i in 0 .. 4095 do yield i }
printfn "%b" (s :? IEnumerable<int>) // true
printfn "%b" (s :? IEnumerator<int>) // true
Run Code Online (Sandbox Code Playgroud)
但Seq.init不是:
let s = Seq.init 4095 (fun i -> i)
printfn "%b" (s :? IEnumerable<int>) // true
printfn "%b" (s :? IEnumerator<int>) // false
Run Code Online (Sandbox Code Playgroud)
你可以重构你的代码IEnumerable<T>而不是IEnumerator因为两个结构都产生了IEnumerable<T>.
或者,如果你真的想要的IEnumerator,你可以简单地调用GetEnumerator返回的Enumerator从Enumerable:
let s = (Seq.init 4095 (fun i -> i)).GetEnumerator()
printfn "%b" (s :? IEnumerable<int>) // false
printfn "%b" (s :? IEnumerator<int>) // true
Run Code Online (Sandbox Code Playgroud)
如果查看规范,序列表达式将转换为:
Seq.collect (fun pat -> Seq.singleton(pat)) (0 .. 4095)
Run Code Online (Sandbox Code Playgroud)
如果你看一下Seq.collect它的定义来源是:
let collect f sources = map f sources |> concat
Run Code Online (Sandbox Code Playgroud)
如果你看concat它的定义是:
let concat sources =
checkNonNull "sources" sources
mkConcatSeq sources
Run Code Online (Sandbox Code Playgroud)
mkConcatSeq 定义为:
let mkConcatSeq (sources: seq<'U :> seq<'T>>) =
mkSeq (fun () -> new ConcatEnumerator<_,_>(sources) :> IEnumerator<'T>)
Run Code Online (Sandbox Code Playgroud)
所以你可以看到返回的序列实现了IEnumerator<'T>,因此IEnumerator.
现在Seq.init定义为:
let init count f =
if count < 0 then invalidArg "count" (SR.GetString(SR.inputMustBeNonNegative))
mkSeq (fun () -> IEnumerator.upto (Some (count-1)) f)
Run Code Online (Sandbox Code Playgroud)
并mkSeq定义为:
let mkSeq f =
{ new IEnumerable<'U> with
member x.GetEnumerator() = f()
interface IEnumerable with
member x.GetEnumerator() = (f() :> IEnumerator) }
Run Code Online (Sandbox Code Playgroud)
所以它只实现IEnumerable<'T>而不是IEnumerator.
| 归档时间: |
|
| 查看次数: |
559 次 |
| 最近记录: |