F# 中的二维数组上的 Foreach 使编译器认为迭代值是对象类型。为什么?
Foreach over a 2D Array in F# makes the compiler think the iterated values are of type object. Why?
我在这个看似简单的问题上遇到了麻烦:
let xs = Array2D.init 3 3 (fun j i -> j*3 + i)
printfn "%O" (xs.GetType()) // prints System.Int32[,]
for v in xs do
printfn "%d" v // <- this gives a compiler error. why should it?
问题似乎是 F# 认为 v
是类型 obj
,这有点奇怪。
这是编译器错误还是我遗漏了一些非常明显的东西?
谢谢
如果我们反思 System.Int32[,]
类型,xs
属于它,我们可能会观察到它只实现了非泛型 System.Collections.IEnumerable
接口,所以在
脱糖之后
for v in xs do...
转化为等价物
let xe = xs.GetEnumerator()
while xe.MoveNext() do
let v = xe.Current
...
我们可以看出为什么上面的 v
是 obj
类型——这是 System.Collections.IEnumerable.Current 属性.
的类型
编辑:但是,如果将 int[,]
的 xs
类型显式转换为 seq<int>
,如下所示:
for v in Seq.cast<int> xs do
printfn "%d" v
也就是说,v
现在属于 int
类型,编译器很满意。
我在这个看似简单的问题上遇到了麻烦:
let xs = Array2D.init 3 3 (fun j i -> j*3 + i)
printfn "%O" (xs.GetType()) // prints System.Int32[,]
for v in xs do
printfn "%d" v // <- this gives a compiler error. why should it?
问题似乎是 F# 认为 v
是类型 obj
,这有点奇怪。
这是编译器错误还是我遗漏了一些非常明显的东西?
谢谢
如果我们反思 System.Int32[,]
类型,xs
属于它,我们可能会观察到它只实现了非泛型 System.Collections.IEnumerable
接口,所以在
for v in xs do...
转化为等价物
let xe = xs.GetEnumerator()
while xe.MoveNext() do
let v = xe.Current
...
我们可以看出为什么上面的 v
是 obj
类型——这是 System.Collections.IEnumerable.Current 属性.
编辑:但是,如果将 int[,]
的 xs
类型显式转换为 seq<int>
,如下所示:
for v in Seq.cast<int> xs do
printfn "%d" v
也就是说,v
现在属于 int
类型,编译器很满意。