F#列表是否持久?
我是一名C#开发人员,不熟悉F#,我知道在.net中字符串是不可变的。换句话说,每次修改字符串时,都会得到一个新的字符串实例 对于像我这样的非功能性思维来说,第一个问题是效率,我理解C#可变对象不是持久的。因为在大多数应用程序中,字符串操作通常是微不足道的 我的问题是,F#列表也是这样吗?F#会克隆每一个变化的列表吗?例如,在筛选列表时,我是否创建一个包含较少项目的新列表 更新:我没有比较.net字符串和列表。我将string命名为不可变对象的一个示例,并想知道F#是否对它的列表进行了特殊处理 这就是我所说的“.F#列表是链接列表。因此,当您创建一个新列表时,它只需将项目添加到现有列表中,并指向包含新项目的头部。原始列表仍然指向创建该列表时的标题项。换句话说,它们都指向同一个列表中不同的位置。F#列表是不可变的。没有“修改”F#列表的API,因此不涉及克隆。像F#列表是否持久?,f#,performance,immutability,persistent,F#,Performance,Immutability,Persistent,我是一名C#开发人员,不熟悉F#,我知道在.net中字符串是不可变的。换句话说,每次修改字符串时,都会得到一个新的字符串实例 对于像我这样的非功能性思维来说,第一个问题是效率,我理解C#可变对象不是持久的。因为在大多数应用程序中,字符串操作通常是微不足道的 我的问题是,F#列表也是这样吗?F#会克隆每一个变化的列表吗?例如,在筛选列表时,我是否创建一个包含较少项目的新列表 更新:我没有比较.net字符串和列表。我将string命名为不可变对象的一个示例,并想知道F#是否对它的列表进行了特殊处理
List.filter
这样的操作会创建一个新的列表(如果可能的话,它可能与原始列表共享一些结构)
(我认为任何语言中的所有不可变对象都是这样工作的。)
见例
请提供一个很好的描述以及一些图片来说明共享是如何工作的。我认为在解释列表不变性方面做得非常出色
在函数世界中,列表是不可变的。这意味着节点共享是可能的,因为原始列表永远不会更改。由于第一个列表以空列表结尾,因此必须复制其节点,以便将其最后一个节点指向第二个列表。追加操作后,我们的列表如下所示:
在这一点上,你们当中更怀疑的人可能会说,“嗯,
这是一个非常有趣的理论,但你能证明它吗?”
没问题
利用F#列表是递归的知识,我们可以检索
通过取
尾巴,它的尾巴,它的尾巴。tl是F#
用于提取列表的尾部
> let lastHalf = List.tl (List.tl (List.tl combined));;
val lastHalf : int list
> lastHalf;;
val it : int list = [4; 5; 6]
最后,因为F#是.NET框架的一流公民,我们
具有对所有基类库的完全访问权限。所以,我们可以使用
Object.ReferenceEquals
方法来测试是否为最后一半
第二种情况确实相同
> System.Object.ReferenceEquals(lastHalf, second);;
val it : bool = true
就在这里。信不信由你,加上两个不变的
列表实际上可以比追加更快、更节省内存
可变列表,因为需要复制的节点较少
理解函数式语言列表的最佳方法是理解我认为Dan和Brian的参考应该直接回答您的问题。如果您想了解更多信息,还可以查看以下材料(本周在MSDN上发布),这些材料是为向.NET开发人员解释F#和功能概念而编写的:
- 介绍F#列表并展示如何在C#中实现相同的概念,这是了解列表如何工作(以及哪些操作是有效的)的一个很好的方法
- 提供更多关于F#中不变性的背景信息-它不会直接回答您的问题,但也可能是一个有用的资源