在F#中对2D数组进行探查使编译器认为迭代值是对象类型。为什么?
我在这个看似简单的问题上遇到了麻烦:
I'm having trouble in this seemingly simple issue:
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
,这有点奇怪。
The problem seems to be that F# thinks v
is of type obj
, which is kind of odd.
这是编译器错误还是我丢失了某些内容
Is this a compiler bug or am I missing something perfectly obvious?
谢谢
如果我们反映为类型 System.Int32 [,]
,它是 xs
的缩写,我们可能会观察到它仅实现非通用的 System.Collections。 IEnumerable
界面,所以在废止
If we reflect into type System.Int32[,]
, which xs
is of, we may observe that it implements only non-generic System.Collections.IEnumerable
interface, so after desugaring
for v in xs do...
转换为等效值
let xe = xs.GetEnumerator()
while xe.MoveNext() do
let v = xe.Current
...
我们可以看到上面的 v
为什么是 obj
-这是 System.Collections.IEnumerable.Current 属性。
we can see why v
above is of type obj
- this is the type of System.Collections.IEnumerable.Current property.
编辑:但是,如果显式强制转换 xs
类型的 int [ ,]
到 seq< int>
,如下所示:
EDIT: However, if explicitly cast xs
type of int[,]
to seq<int>
, like below:
for v in Seq.cast<int> xs do
printfn "%d" v
即 v
现在的类型为 int
,编译器很高兴。
that is, v
is now of type int
and compiler is happy.