问题标签 [immutability]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
7 回答
4598 浏览

c# - 如何确定一个类在 C# 中是否不可变?

如何确定一个类在 C# 中是否不可变?

0 投票
9 回答
18488 浏览

.net - System.String.Copy 在 .NET 中有什么用?

恐怕这是一个非常愚蠢的问题,但我一定遗漏了一些东西。

为什么要使用String.Copy(string)

文档说方法

创建一个新的 String 实例,其值与指定的 String 相同。

由于字符串在 .NET 中是不可变的,所以我不确定使用这种方法有什么好处,因为我认为

出于所有实际目的,似乎会产生与

也就是说,除了正在进行的任何内部簿记以及复制不是ReferenceEquals到 otherString 的事实之外,没有可观察到的差异 - String 是一个不可变类,其相等性基于值,而不是身份。(感谢@Andrew Hare 指出我最初的措辞不够精确,无法表明我意识到Copying 和 not 之间存在差异,但担心缺乏有用的差异。)

当然,当传递一个null参数时, Copy 会抛出一个ArgumentNullException,并且“新实例”可能会消耗更多内存。后者似乎几乎没有好处,而且我不确定 null 检查是否足以保证整个 Copy 方法的好处。

谢谢。

0 投票
75 回答
16310 浏览

language-agnostic - 不可变集合上的非变异“添加”方法的最佳名称是什么?

很抱歉标题有点啰嗦——如果我能想出一个简洁的标题,我就不必问这个问题了。

假设我有一个不可变的列表类型。它有一个操作,该操作Foo(x)返回一个新的不可变列表,其中指定的参数作为末尾的额外元素。因此,要建立一个值为“Hello”、“immutable”、“world”的字符串列表,您可以编写:

(这是 C# 代码,如果您觉得语言很重要,我对 C# 建议最感兴趣。从根本上说,这不是语言问题,但语言的习语可能很重要。)

重要的是现有列表不会被更改Foo- 所以empty.Count仍然会返回 0。

获得最终结果的另一种(更惯用的)方法是:

我的问题是:Foo 最好的名字是什么?

编辑 3:正如我稍后透露的那样,类型的名称实际上可能不是ImmutableList<T>,这使位置清楚。相反,想象一下它是TestSuite并且它是不可变的,因为它所属的整个框架都是不可变的......

(编辑 3 结束)

到目前为止我提出的选项:

  • Add:在 .NET 中很常见,但意味着原始列表的突变
  • Cons: 我相信这是函数式语言中的正常名称,但对于那些没有使用此类语言经验的人来说毫无意义
  • Plus: 到目前为止我最喜欢的,这对我来说并不意味着突变。显然这也在Haskell 中使用,但期望略有不同(Haskell 程序员可能希望它将两个列表添加在一起,而不是向另一个列表添加单个值)。
  • With:与其他一些不可变的约定一致,但在 IMO 中没有完全相同的“附加性”。
  • And: 不是很详细。
  • + 的运算符重载:我真的不喜欢这个;我一般认为运算符应该只应用于较低级别的类型。不过我愿意被说服!

我用来选择的标准是:

  • 给出方法调用结果的正确印象(即它是带有额外元素的原始列表)
  • 尽可能清楚地表明它不会改变现有列表
  • 像上面的第二个例子一样,当链接在一起时听起来很合理

如果我不够清楚,请询问更多详细信息...

编辑 1:Plus这是我更喜欢Add. 考虑这两行代码:

在我看来(这个人的事情),后者显然是有问题的——就像写“x + 5;”一样。作为自己的声明。第一行看起来没问题,直到您记住它是不可变的。Plus事实上,加号运算符本身不会改变其操作数的方式是我最喜欢的另一个原因。如果没有运算符重载的轻微恶心,它仍然给出相同的含义,其中包括(对我而言)不改变操作数(或在这种情况下的方法目标)。

编辑2:不喜欢添加的原因。

各种答案都是有效的:“使用 Add。这就是DateTime它的作用,并且String具有Replace不会使不变性明显的方法等。” 我同意 - 这里有优先级。但是,我看到很多人打电话DateTime.AddorString.Replace期待 mutation。有很多新闻组问题(如果我仔细研究的话,可能还有一些问题),这些问题的答案是“你忽略了 ; 的返回值String.Replace;字符串是不可变的,会返回一个新字符串。”

现在,我应该揭示这个问题的一个微妙之处——该类型实际上可能不是一个不可变列表,而是一个不同的不可变类型。特别是,我正在开发一个基准测试框架,您可以在其中向套件添加测试,并创建一个新套件。可能很明显:

不会完成任何事情,但是您将其更改为:

看起来应该没问题。而对我来说,这使错误更清楚:

那只是乞求:

理想情况下,我希望我的用户不必被告知测试套件是不可变的。我要他们掉进成功的坑里。这可能是不可能的,但我想试试。

对于通过仅谈论不可变列表类型来过度简化原始问题,我深表歉意。ImmutableList<T>并非所有收藏都像:)那样具有自我描述性

0 投票
4 回答
1541 浏览

c# - 在 C# 中传递和存储指向不可变类型和字符串的指针

有没有办法在 C# 中存储指向不可变类型(如字符串)的指针?如何执行:Instance1.SomeFunction(out MyString);

,并在 Instance1 中存储指向 MyString 的指针?

0 投票
3 回答
14723 浏览

c# - C# 是否(或将)包含用于副作用验证的功能?

我知道 C# 得到了很多并行编程支持,但是 AFAIK 仍然没有用于副作用验证的构造,对吗?

我认为既然 C# 已经布局,那就更棘手了。但是有计划把它放进去吗?还是 F# 是唯一具有副作用验证构造的 .NET 语言?

0 投票
9 回答
6269 浏览

data-structures - Are some data structures more suitable for functional programming than others?

In Real World Haskell, there is a section titled "Life without arrays or hash tables" where the authors suggest that list and trees are preferred in functional programming, whereas an array or a hash table might be used instead in an imperative program.

This makes sense, since it's much easier to reuse part of an (immutable) list or tree when creating a new one than to do so with an array.

So my questions are:

  • Are there really significantly different usage patterns for data structures between functional and imperative programming?
  • If so, is this a problem?
  • What if you really do need a hash table for some application? Do you simply swallow the extra expense incurred for modifications?
0 投票
9 回答
12985 浏览

c# - 结构的不变性

可能重复:
为什么可变结构是邪恶的?

我在很多地方都读过它,包括这里,最好将结构设为不可变。

这背后的原因是什么?我看到许多 Microsoft 创建的可变结构,例如 xna 中的结构。BCL 中可能还有更多。

不遵守本指南的利弊是什么?

0 投票
10 回答
166246 浏览

ruby - 为什么在 Ruby 方法中使用感叹号?

在 Ruby中,一些方法有?一个问号(include?

但是为什么有些方法有感叹号(!)而其他方法没有呢?

这是什么意思?

0 投票
15 回答
9473 浏览

oop - 什么是不变性,我为什么要担心它?

我已经阅读了几篇关于不变性的文章,但仍然没有很好地遵循这个概念。

我最近在这里发了一个帖子,其中提到了不变性,但是由于这本身就是一个主题,所以我现在正在制作一个专门的帖子。

我在过去的帖子中提到,我认为不变性是使对象只读并赋予其低可见性的过程。另一位成员说这与那件事没有任何关系。此页面系列的一部分)使用不可变类/结构的示例,并使用只读和其他概念将其锁定。

在这个例子中,状态的定义到底是什么?状态是一个我还没有真正掌握的概念。

从设计指南的角度来看,不可变类必须是不接受用户输入并且真的只返回值的类?

我的理解是,任何只返回信息的对象都应该是不可变的并且“锁定”,对吗?因此,如果我想使用该方法在专用类中返回当前时间,我应该使用引用类型,因为它可以作为类型的引用,因此我可以从不变性中受益。

0 投票
7 回答
1069 浏览

c++ - 如何在 C++ 中按值传递引用?

我正在尝试在 C++ 中创建不可变类型(类),

我这样做是为了让所有方法“又名成员函数”都不会修改对象并返回一个新实例。

我遇到了很多问题,但它们都围绕 C++ 中的引用类型。

一个示例是通过引用传递相同类类型的参数时:

该错误是由通过引用传递值引起的。相反,如果我是按值传递引用,那么上面的错误行就不会是错误!

考虑一个 Java/C# 示例

我怎样才能在 C++ 中做这样的事情?我知道我可以使用指针,但后来我遇到了整个内存管理混乱。我不想担心谁拥有对对象的引用。

理想情况下,我想将类设计为类似于 python 中的不可变字符串;您可以在没有注意到甚至不知道它们是不可变的情况下使用它们,并且它们的行为符合您的预期;他们只是工作。

编辑

当然,我可以通过按值传递或使用临时变量(这是我目前正在做的)来解决它。我要问的是“如何在 C++ 中按值传递引用”

我期待答案围绕 STL 中的某些内容展开,我目前正在研究 smart_ptr 模板系列。

更新

感谢您的回复,我意识到指针无法逃脱。(见我的另一个问题,这真的是对这个问题的跟进)