可能重复:
为什么可变结构是邪恶的?
我在很多地方阅读它,包括在这里最好将结构化为不可变的.
这背后的原因是什么?我看到许多微软创建的结构是可变的,就像xna中那样.可能在BCL还有更多.
不遵守本指南的利弊是什么?
我一直在考虑如何将deque(即双端队列)实现为不可变数据结构.
似乎有不同的方法来做到这一点.AFAIK,不可变数据结构通常是分层的,因此在修改诸如插入或删除项之类的操作之后,可以重用它的主要部分.
Eric Lippert 在他的博客上有两篇 关于这个主题的文章,以及C#中的示例实现.
他的两个实现都让我觉得比实际需要更精细.难道deques只能被实现为二叉树,其中元素只能在树的"左"(前)和非"右"(后面)插入或删除?
o
/ \
… …
/ \
… …
/ \ / \
front --> L … … R <-- back
Run Code Online (Sandbox Code Playgroud)
此外,树将与旋转保持合理平衡:
在我看来,Eric Lippert是一个非常聪明的人,我非常尊重他,但他显然没有考虑这种方法.因此我想知道,这是有充分理由的吗?我建议的实施dequesnaïve的方法吗?
考虑以下代码:
a = {...} # a is an dict with arbitrary contents
b = a.copy()
Run Code Online (Sandbox Code Playgroud)
如何检查Python中的类型是否可变?
由于尽管在CLR中有一些支持,但不变性并没有完全融入C#到F#的程度,或完全进入框架(BCL),对于C#的(im)可变性有什么相当完整的解决方案?
我的偏好顺序是一个由兼容的一般模式/原则组成的解决方案
那
我还希望包含您作为社区可能提出的模式,这些模式不完全适合框架,例如通过接口表达可变性意图(其中两个客户端不应该更改某些内容并且可能只想更改某些内容通过接口这样做,而不是支持类(是的,我知道这不是真正的不变性,但足够):
public interface IX
{
int Y{ get; }
ReadOnlyCollection<string> Z { get; }
IMutableX Clone();
}
public interface IMutableX: IX
{
new int Y{ get; set; }
new ICollection<string> Z{ get; } // or IList<string>
}
// generally no one should get ahold of an X directly
internal class X: IMutableX
{
public int Y{ get; set; }
ICollection<string> IMutableX.Z …Run Code Online (Sandbox Code Playgroud) 我正在使用一个使用json的API.我有一些我为API建模而创建的类.为了简化生活,我的模型使用公共属性,当将json反序列化为对象时,Json.Net又使用公共属性.
我想使我的对象不可变,但我遇到了一个问题,因为如果我将我的属性设为只读,我就会打破反序列化.有没有办法让我拥有不可变对象,并使用反序列化?
有可能以某种方式将a标记System.Array为不可变.当置于public-get/private-set之后,它们无法添加,因为它需要重新分配和重新分配,但消费者仍然可以设置他们希望的任何下标:
public class Immy
{
public string[] { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
我认为readonly关键字可能会成功,但没有这样的运气.
StringBuiler是一个可变对象,F#鼓励尽可能多地使用不变性.所以应该使用转换而不是变异.在F#中构建字符串时,这是否适用于StringBuilder?有一个F#immutable替代它吗?如果是这样,这种替代方案是否有效?
到目前为止,大多数"起始锅炉板"和一些关于react/redux的帖子我都看到鼓励使用immutable.js来解决可变性问题.我个人依赖Object.assign或传播运算符来处理这个问题,因此在immutable.js中并没有真正看到优势,因为它增加了额外的学习,并且从用于可变性的vanilla js技术转移了一些.我试图找到切换的正当理由,但是因为我无法在这里询问为什么它如此受欢迎.
我尝试从Seq构造不可变集/映射.我目前正在做以下事情:
val input: Seq[(String, Object)] = //.....
Map[String, Object]() ++ input
Run Code Online (Sandbox Code Playgroud)
和集合
val input: Seq[String] = //.....
Set[String]() ++ input
Run Code Online (Sandbox Code Playgroud)
这似乎有点复杂,有更好的方法吗?
我正在寻找这个问题的惯用解决方案.
我正在构建一个valScala(不可变)地图,并希望可选择添加一个或多个项目:
val aMap =
Map(key1 -> value1,
key2 -> value2,
(if (condition) (key3 -> value3) else ???))
Run Code Online (Sandbox Code Playgroud)
如何在不使用var?的情况下完成?什么应该取代????使用+运营商更好吗?
val aMap =
Map(key1 -> value1,
key2 -> value2) +
(if (condition) (key3 -> value3) else ???))
Run Code Online (Sandbox Code Playgroud)
一种可能的解决方案是
val aMap =
Map(key1 -> value1,
key2 -> value2,
(if (condition) (key3 -> value3) else (null, null))).filter {
case (k, v) => k != null && v != null
}
Run Code Online (Sandbox Code Playgroud)
这是最好的方法吗?
immutability ×10
c# ×4
.net ×3
scala ×2
arrays ×1
deque ×1
f# ×1
hashable ×1
javascript ×1
json.net ×1
mutable ×1
python ×1
python-2.x ×1
python-3.x ×1
reactjs ×1
redux ×1
struct ×1