标签: immutability

为什么Matz默认在Ruby中选择使Strings变为可变?

这与此问题相反:为什么字符串在Java和.NET中不可变?

这种选择是否仅仅因为操作(追加等)在可变字符串上有效,或者是否有其他原因而在Ruby中进行?

(如果它只是效率,那似乎很奇怪,因为Ruby的设计似乎不会高度重视促进有效的实施.)

ruby string language-design mutable immutability

43
推荐指数
2
解决办法
6224
查看次数

基于先前值更新Map中的值的惯用方法

假设我将银行账户信息存储在一个不可变的Map:

val m = Map("Mark" -> 100, "Jonathan" -> 350, "Bob" -> 65)
Run Code Online (Sandbox Code Playgroud)

我想从马克的帐户中提取50美元.我可以这样做:

val m2 = m + ("Mark" -> (m("Mark") - 50))
Run Code Online (Sandbox Code Playgroud)

但这段代码对我来说似乎很难看.有没有更好的方法来写这个?

scala map immutability

43
推荐指数
4
解决办法
2万
查看次数

关于更改不可变字符串的id

关于id类型对象的某些东西str(在python 2.7中)让我很困惑.该str类型是不变的,所以我希望,一旦它被创建,它将始终具有相同的id.我相信我不会这么说自己,所以我会发布一个输入和输出序列的例子.

>>> id('so')
140614155123888
>>> id('so')
140614155123848
>>> id('so')
140614155123808
Run Code Online (Sandbox Code Playgroud)

所以同时,它一直在变化.但是,在指向该字符串的变量之后,事情会发生变化:

>>> so = 'so'
>>> id('so')
140614155123728
>>> so = 'so'
>>> id(so)
140614155123728
>>> not_so = 'so'
>>> id(not_so)
140614155123728
Run Code Online (Sandbox Code Playgroud)

因此,一旦变量保存该值,它就会冻结id.的确,在del so和之后del not_so,id('so')开始的输出再次改变.

这是相同的行为与(小)整数.

我知道不变性和拥有相同之间没有真正的联系id; 仍然,我试图弄清楚这种行为的来源.我相信那些熟悉python内部的人会比我更少惊讶,所以我试图达到同样的目的......

更新

尝试使用不同的字符串会产生不同的结果......

>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
Run Code Online (Sandbox Code Playgroud)

现在它平等的......

python string immutability python-internals

43
推荐指数
1
解决办法
6851
查看次数

Collections.unmodifiableSet()和Guava的ImmutableSet有什么区别?

JavaDoc ImmutableSet说:

Collections.unmodifiableSet可以更改的单独集合的视图不同,此类的实例包含其自己的私有数据,并且永远不会更改.这个类对于公共静态最终集("常量集")很方便,也可以让你轻松地为调用者提供给你的类的集合制作一个"防御性副本".

ImmutableSet仍然存储元素的参考,我无法弄清楚差异Collections.unmodifiableSet().样品:

StringBuffer s=new StringBuffer("a");
ImmutableSet<StringBuffer> set= ImmutableSet.of(s);
s.append("b");//s is "ab", s is still changed here!
Run Code Online (Sandbox Code Playgroud)

谁能解释一下呢?

java immutability guava

42
推荐指数
3
解决办法
3万
查看次数

如何在Java中识别不可变对象

在我的代码中,我正在创建一个对象集合,这些对象将以各种线程的方式访问,只有在对象是不可变的情况下才是安全的.当尝试将新对象插入到我的集合中时,我想测试它是否是不可变的(如果没有,我会抛出异常).

我能做的一件事就是检查一些众所周知的不可变类型:

private static final Set<Class> knownImmutables = new HashSet<Class>(Arrays.asList(
        String.class, Byte.class, Short.class, Integer.class, Long.class,
        Float.class, Double.class, Boolean.class, BigInteger.class, BigDecimal.class
));

...

public static boolean isImmutable(Object o) {
    return knownImmutables.contains(o.getClass());
}
Run Code Online (Sandbox Code Playgroud)

这实际上让我90%的方式,但有时我的用户会想要创建自己的简单不可变类型:

public class ImmutableRectangle {
    private final int width;
    private final int height;
    public ImmutableRectangle(int width, int height) {
        this.width = width;
        this.height = height;
    }
    public int getWidth() { return width; }
    public int getHeight() { return height; }
}
Run Code Online (Sandbox Code Playgroud)

是否有某种方式(可能使用反射)我可以可靠地检测一个类是否是不可变的?假阳性(认为它不是不可变的)是不可接受的,但是假阴性(认为它是可变的,当它不是)时.

编辑补充:感谢有见地和有帮助的答案.正如一些答案所指出的那样,我忽略了我的安全目标.这里的威胁是无能为力的开发人员 - 这是一个框架代码,将被大量知道线程无关的人使用,不会阅读文档.我不需要为恶意开发者辩护 - 任何聪明到足以变异字符串 …

java functional-programming immutability

41
推荐指数
4
解决办法
2万
查看次数

.clone()或Arrays.copyOf()?

为了减少可变性,我们应该使用

public void setValues(String[] newVals) {

     this.vals = ( newVals == null ? null : newVals.clone() );
}
Run Code Online (Sandbox Code Playgroud)

要么

public void setValues(String[] newVals) {

     this.vals = ( newVals == null ? null : Arrays.copyOf(newVals, newVals.length) );
}
Run Code Online (Sandbox Code Playgroud)

java immutability

41
推荐指数
2
解决办法
4万
查看次数

如何创建ImmutableDictionary的新实例?

我想写这样的东西:

var d = new ImmutableDictionary<string, int> { { "a", 1 }, { "b", 2 } };
Run Code Online (Sandbox Code Playgroud)

(使用ImmutableDictionary来自System.Collections.Immutable).这似乎是一个简单的用法,因为我预先声明了所有的价值 - 那里没有变异.但这给了我错误:

类型' System.Collections.Immutable.ImmutableDictionary<TKey,TValue>'没有定义构造函数

我应该如何用静态内容创建一个新的不可变字典?

c# immutability .net-4.5

41
推荐指数
5
解决办法
1万
查看次数

为什么这个类可变?

public class Test {
    private final String url;
    public Test(String url) {
        this.url = url;
    }
    public String getUrl() {
        return url;
    }
}
Run Code Online (Sandbox Code Playgroud)

Test类有:

  1. 只有一个私有和最终的实例变量.
  2. 没有二传手.
  3. 初始化实例变量的唯一方法是通过构造函数.
  4. 一旦设置了URL,即使在getUrl中也不能修改它,即使该方法被Test的任何子类覆盖.

但是我正在阅读的一本书说上面的Test类是可变的,因为:

  • 这两个类都不是最终的,因此它可以扩展,并且子类可以覆盖实例方法.但Test类实际上没有构造函数以外的任何实例方法.

  • 构造函数也不是私有的.

你能帮我理解为什么Test类是可变的吗?

java immutability

41
推荐指数
1
解决办法
2740
查看次数

值类型是否按定义不可变?

我经常读到structs应该是不可变的 - 根据定义它们不是吗?

你认为int是不可改变的吗?

int i = 0;
i = i + 123;
Run Code Online (Sandbox Code Playgroud)

似乎没关系 - 我们得到一个新的int并将其分配给i.那这个呢?

i++;
Run Code Online (Sandbox Code Playgroud)

好的,我们可以把它想象成一条捷径.

i = i + 1;
Run Code Online (Sandbox Code Playgroud)

怎么样struct Point

Point p = new Point(1, 2);
p.Offset(3, 4);
Run Code Online (Sandbox Code Playgroud)

这真的改变了这一点(1, 2)吗?我们难道不应该将它视为Point.Offset()返回新点的下列捷径吗?

p = p.Offset(3, 4);
Run Code Online (Sandbox Code Playgroud)

这种想法的背景是这样的 - 没有身份的价值类型怎么可能是可变的?您必须至少查看两次以确定它是否发生了变化.但是如果没有身份,你怎么能这样做呢?

我不想通过考虑ref参数和拳击来使这个推理复杂化.我也知道,p = p.Offset(3, 4);表达不变性比做得好p.Offset(3, 4);.但问题仍然存在 - 根据定义,值不是不可变的值吗?

UPDATE

我认为至少涉及两个概念 - 变量或字段的可变性以及变量值的可变性.

public class Foo
{
    private Point point; …
Run Code Online (Sandbox Code Playgroud)

.net c# immutability value-type

40
推荐指数
4
解决办法
9421
查看次数

如何从Java中的特定字符串中删除特定字符?

例如,我从文本文件中提取文本字符串,我需要这些字来形成一个数组.但是,当我做所有这些时,一些单词以逗号(,)或句号(.)结尾,或者甚至附加括号(这都是完全正常的).

我想要做的就是摆脱那些角色.我一直试图在Java中使用那些预定义的String方法来做到这一点,但我无法解决它.

java string immutability

40
推荐指数
3
解决办法
13万
查看次数