F Sharp 中的 List<int> 与 int 列表

标签 list generics f#

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 listList<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 listlist<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/

    相关文章:

    interface - 有没有更简单的方法在 F# 中隐式使用接口(interface)?

    php - 在 PHP、JavaScript 中执行此 Python 3 列表操作的最短方法?

    c++ - 在指针列表中找到一个项目

    list - 将列表元素与其索引相关联的 Pythonic 方式

    java - 实例化通用对象

    forms - F# 将按钮列表添加到表单控件范围

    f# - F#列表选择很多

    ruby - 在 Ruby 中重新排列一维列表

    java - 设置<?不允许使用 extends MyClass> 作为对象声明

    c# - 将字典键设置为对象类型