有什么区别List<int>和int list?例如,当我写一个函数
let somefn a : int list = a
Run Code Online (Sandbox Code Playgroud)
和
let somefn2 a : List<int> = a
Run Code Online (Sandbox Code Playgroud)
返回值类型因符号样式而异,甚至在控制台输出中,当我调用这些函数时,它会显示两种明显不同的类型
val it : int list = ...
Run Code Online (Sandbox Code Playgroud)
和
val it : List<int> = ...
Run Code Online (Sandbox Code Playgroud)
虽然逻辑和想法似乎相同,但解释器/编译器以不同的方式解释这两种类型.
有什么区别吗?
rmu*_*unn 18
要稍微扩展John Palmer的正确答案,这里是一个F#交互式会话,说明了如何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"
Run Code Online (Sandbox Code Playgroud)
因此List<int>,对于大写的L,将是F#列表类型(具有头指针的不可变链表,如果尚未打开System.Collections.Generic命名空间,则具有O(1)头访问和前置,但O(N)尾访问和追加).但是,如果你有,那么突然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#单链接列表类型,但如果打开命名空间,则更改 C#类型的含义System.Collections.Generic).作为一般规则,请勿使用此类型名称; 如果你想在F#中使用这种类型,请ResizeArray<int>改用.没有区别,有一个类型别名.
除了一个案例,你已经跑了
open System.Collections.Generic
Run Code Online (Sandbox Code Playgroud)
哪个有自己的列表类型