F# 未选中列表中的.defaultof
考虑:F# 未选中列表中的.defaultof,f#,F#,考虑: > Unchecked.defaultof<list<int>>;; val it : int list = null > 2 :: 1 :: Unchecked.defaultof<list<int>>;; val it : int list = [2] >未选中。defaultof;; val it:int list=null >2::1::未选中。defaultof;; val it:int list=[2] 这种行为
> Unchecked.defaultof<list<int>>;;
val it : int list = null
> 2 :: 1 :: Unchecked.defaultof<list<int>>;;
val it : int list = [2]
>未选中。defaultof;;
val it:int list=null
>2::1::未选中。defaultof;;
val it:int list=[2]
这种行为背后的原因是什么?我希望最后的列表是[2;1]或者提出一个例外。这是一个非常令人惊讶的问题。我看了F#list是如何编译的,它解释了这种行为。我不认为这是bug(这就是为什么<代码>默认代码在<代码>未选中< /代码>模块中,也可能烧毁您的计算机! 首先,空列表
[]
在F#2.0中不表示为null
,因为这样您将无法调用空列表上的方法-这将破坏许多事情(例如将空列表传递给任何Seq
函数)。另一方面,为了提高效率,None
值表示为null
,这意味着选项
接口,即使它有意义
因此,F#使用一个特殊值
list.Empty
来表示空列表。现在,这个值与表示非空列表的值是同一类型的实例(类型是fsharplist,这很奇怪。你怎么会偶然发现这样的东西?;)使用Array.zeroCreate初始化列表数组似乎很自然。我知道它会使用Unchecked.defaultof,但我认为最坏的情况是例外。但显然我错得很厉害。这可能是因为F#假设很多东西都不是空的-注意未选中.defaultof[]
。我猜第一个cons调用会以某种方式把东西扔掉,同时1::null
会抛出一个异常。可能defaultof
应该返回[]
而不是null
,但是等待-它变得更奇怪->匹配1::Unchecked.defaultof with-| 1::|->printfn“有一个”-|->printfn“wtf”;;有一个
和1::Unchecked.defaultof |>List.length;;val it:int=0
我认为这应该通过电子邮件发送到F#bugs电子邮件-fsbugs@microsoft.comBut那么所有的零创建函数呢?
let rec iter (xs:int list) =
match list with
| x::xs -> Console.WriteLine(x); iter xs
| [] -> ()
if (list.TailOrNull != null) {
Console.WriteLine(list.HeadOrDefault);
iter(list.TailOrNull);
}