【问题标题】:F#, why can't I access the "Item" memberF#,为什么我不能访问“项目”成员
【发布时间】:2013-06-06 17:05:49
【问题描述】:

在 F# 中,为什么我不能在这里访问 Array 上的“Item”成员:

let last (arr:System.Array) =
    let leng = arr.Length
    arr.[leng-1]   // Error: Field, constructor or member "Item" is not defined.

【问题讨论】:

  • System.Array 没有Item 成员,您需要改用GetValue(int)。但是,您可能不想直接使用System.Array

标签: arrays f#


【解决方案1】:

你可以试试这个吗?

let last (arr:_[]) =
       let leng = arr.Length
       arr.[leng-1]

【讨论】:

  • 因为 [] 不是 System.Array 而是继承自它? [] 是什么?
  • @Goswin 你可以把System.Array看作是所有具体数组类型的抽象基类,比如int[]。重要的是缺少类型参数。编译器应该如何知道你的数组包含什么样的元素。 Object 作为所有类型的基类型并不是一个好的答案,因为类型安全无法静态保证。 Wei Ma 的回答定义了一个通用函数。这样你就可以处理具体的数组类型。 _[] 使用通配符语法绕过定义类型参数。 'a[] 将是等效的。它是一个“'a”的数组,是System.Array的子类型
  • @ChristianKlauser @Lee 我在哪里可以查到[] 是什么?我在哪里可以查到 [] 有一个名为 Item 的成员?是here 吗?
  • @Goswin 所以你提到的最后一个链接是关于名为 Array 的 module 的。我知道,它只会变得更好;)。不过,这里有一些教训:模块是您在函数式方法中放置大部分(全部?)函数的地方,即:一个数据结构,尽可能“类型显式”,并且以模块分组的函数列表。例如,您有 Seq 模块、序列 (=IEnumerable) 结构、Async 模块和异步构建器等...
  • 泛型数组类型注解的其他等效语法:array<_>array<'a>_ array'a array
【解决方案2】:

这似乎是一个普遍的 dotnet 事情。查找documentation我看到了

Array 类是语言实现的基类 支持数组。但是,只有系统和编译器可以导出 显式地从 Array 类中。用户应该使用数组 语言提供的结构。

【讨论】:

【解决方案3】:

另外,请注意,在 F# 中,您通常会使用不可变列表:

let last (stuff: _ list) =
    let l = stuff.Length
    stuff.[l]

但如果您使用的是列表,则应使用more efficient algorithm; F# 列表是链表:

let rec last = function
    | hd :: [] -> hd
    | hd :: tl -> last tl
    | _ -> failwith "Empty list."

【讨论】:

  • stuff.Lengthstuff.[l] 都是 O(N) 操作——都不应该在惯用的 F# 代码中使用。
  • 好的,我会改进这个答案。
猜你喜欢
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
相关资源
最近更新 更多