List<int>
有什么区别吗和 int list
?
例如,当我写一个函数时
let somefn a : int list = a
和
let somefn2 a : List<int> = a
返回值类型因符号样式而异,即使在控制台输出中,当我调用这些函数时,它也会显示两种明显标注的类型
val it : int list = ...
和
val it : List<int> = ...
虽然逻辑和想法似乎相同,但解释器/编译器以不同的方式解释这两种类型。
有什么区别吗?
最佳答案
为了稍微扩展 John Palmer 的正确答案,这里有一个 F# Interactive session ,它说明 int list
和 List<int>
是同义词,直到它们不是同义词的那一刻。并注意如何还有 list<int>
和 ResizeArray<int>
用于额外的混淆:
F# Interactive for F# 4.0 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> typeof<list<int>>.Namespace ;;
val it : string = "Microsoft.FSharp.Collections"
> typeof<list<int>>.Name ;;
val it : string = "FSharpList`1"
> typeof<List<int>>.Namespace ;;
val it : string = "Microsoft.FSharp.Collections"
> typeof<List<int>>.Name ;;
val it : string = "FSharpList`1"
> typeof<int list>.Namespace ;;
val it : string = "Microsoft.FSharp.Collections"
> typeof<int list>.Name ;;
val it : string = "FSharpList`1"
> typeof<ResizeArray<int>>.Namespace ;;
val it : string = "System.Collections.Generic"
> typeof<ResizeArray<int>>.Name ;;
val it : string = "List`1"
-
- printfn "Now we'll open System.Collections.Generic. Watch what happens."
- ;;
Now we'll open System.Collections.Generic. Watch what happens.
val it : unit = ()
> open System.Collections.Generic ;;
> typeof<list<int>>.Namespace ;;
val it : string = "Microsoft.FSharp.Collections"
> typeof<list<int>>.Name ;;
val it : string = "FSharpList`1"
> typeof<List<int>>.Namespace ;;
val it : string = "System.Collections.Generic"
> typeof<List<int>>.Name ;;
val it : string = "List`1"
> typeof<int list>.Namespace ;;
val it : string = "Microsoft.FSharp.Collections"
> typeof<int list>.Name ;;
val it : string = "FSharpList`1"
> typeof<ResizeArray<int>>.Namespace ;;
val it : string = "System.Collections.Generic"
> typeof<ResizeArray<int>>.Name ;;
val it : string = "List`1"
因此,带有大写 L 的
List<int>
将是 F# 列表类型(一个带有头指针的不可变链表,它具有 O(1) 头访问和前置,但 O(N) 尾访问和附加)如果你还没有打开System.Collections.Generic
命名空间。但是如果你有,那么突然 List<int>
解析为 .Net System.Collections.Generic.List<T>
类,这是一个可变数据结构,在任何地方都有 O(1) 查找,分摊 O(1) 追加,但 O(N) 前置。所以你使用的是哪一个真的很重要。为了安全起见,如果您打算使用 F# 列表结构,我会将其写为
int list
(我的偏好,因为它读起来像英语)或 list<int>
(有些人更喜欢,因为它读起来像 C#)。当您打开 .Net 命名空间时,它们都不会突然获得不同的含义;他们将继续引用 F# 列表结构。并避免使用 List<int>
来引用 F# 列表;仅当您打开 System.Collections.Generic
命名空间并打算获得 .Net System.Collections.Generic.List<T>
实例时才使用它。最后,请注意,在 F# 中,System.Collections.Generic.List<T>
具有可用的类型别名,而无需打开 System.Collections.Generic
命名空间。默认情况下,无需打开任何命名空间,您可以使用名称 ResizeArray<T>
访问此类型。概括:
安全类型名称 :
int list
和 list<int>
(总是指 F# 单链表类型) ResizeArray<int>
(总是指C# System.Collections.Generic.List<T>
类型) 不安全类型名称 因为它们的含义根据您打开的命名空间而变化:
List<int>
(起初指的是F#单向链表类型,但如果打开System.Collections.Generic
命名空间,意义就变成了C#类型)。作为一般规则,不要使用这个类型名称;如果您想在 F# 中使用这种类型,请改用 ResizeArray<int>
。 关于F Sharp 中的 List<int> 与 int 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41092845/