将collection.immutable.Set转换为collection.mutable.Set的最佳方法是什么?
我想知道从程序员的角度来看,字符串类型是不可变的好处.
技术优势(在编译器/语言方面)可以概括为,如果类型是不可变的,则更容易进行优化.请阅读此处了解相关问题.
另外,在一个可变的字符串类型中,要么你已经内置了线程安全(然后再次,优化更难),或者你必须自己做.在任何情况下,您都可以选择使用具有内置线程安全性的可变字符串类型,因此这不是不可变字符串类型的优势.(同样,更容易进行处理和优化以确保不可变类型的线程安全,但这不是重点.)
但是不可变字符串类型在使用中有什么好处?让某些类型不可变而其他类型不可变的重点是什么?这对我来说似乎很不一致.
在C++中,如果我想要一些字符串是不可变的,我将它作为const引用传递给function(const std::string&).如果我想要一个原始字符串的可更改副本,我将其作为传递std::string.只有当我想让它变得可变时,我才将它作为reference(std::string&)传递.所以我只能选择我想做的事情.我可以用各种可能的类型做到这一点.
在Python或Java中,某些类型是不可变的(大多数都是基本类型和字符串),而其他类型则不是.
在像Haskell这样的纯函数式语言中,一切都是不可变的.
是否有充分理由说明这种不一致是否有意义?或者仅仅是出于技术上的低级原因?
我需要在Clojure中表示有向图.我想将图中的每个节点表示为一个对象(可能是一个记录),其中包含一个名为" :edges可以从当前节点直接访问的节点集合"的字段.希望不言而喻,但我希望这些图表是不可改变的.
只要我进行拓扑排序并"从叶子上"构建每个图形,我就可以用这种方法构造有向无环图.
但是,这种方法不适用于循环图.我能想到的一个解决方法是为整个图形设置一个单独的集合(可能是地图或矢量).然后:edges,每个节点中的字段将具有键(或索引)到图的边集合中.添加这种额外的间接级别是有效的,因为我可以在他们(将)引用的东西之前创建密钥(或索引),但它感觉就像一个kludge.每当我想要访问一个相邻节点时,我不仅需要进行额外的查找,而且还必须传递全局边缘集合,这感觉非常笨拙.
我听说有些Lisps有办法创建循环列表而不需要使用变异函数.有没有办法在Clojure中创建不可变的循环数据结构?
出于各种原因,我想开始在设计中使用更多不可变类型.目前,我正在使用一个具有如下现有类的项目:
public class IssueRecord
{
// The real class has more readable names :)
public string Foo { get; set; }
public string Bar { get; set; }
public int Baz { get; set; }
public string Prop { get; set; }
public string Prop2 { get; set; }
public string Prop3 { get; set; }
public string Prop4 { get; set; }
public string Prop5 { get; set; }
public string Prop6 { get; set; }
public string Prop7 …Run Code Online (Sandbox Code Playgroud) 我知道,java.lang.String出于安全性和性能相关的原因,该类被声明为final.
我不理解的是,使用所有最终变量和最终方法是否可以实现相同目的而不是声明最终类?
简而言之,下面两个代码片段之间有什么区别...例如
public class final String { .. }
Run Code Online (Sandbox Code Playgroud)
V/S
// non final class
public class String {
// all final variables
private final char[] value;
// all final methods
public final String subString() { .. }
public final int length() { return value.length;}
// etc
}
Run Code Online (Sandbox Code Playgroud)
EDITS
简单来说,我可以通过采用任何一种方法达到相同的不变性水平吗?它们是否都能使对象变得不可变?
请注意,这类似于如何在 asdict 中获取 @property 方法?。
我有一个(冻结的)嵌套数据结构,如下所示。定义了一些(纯粹)依赖于字段的属性。
import copy
import dataclasses
import json
from dataclasses import dataclass
@dataclass(frozen=True)
class Bar:
x: int
y: int
@property
def z(self):
return self.x + self.y
@dataclass(frozen=True)
class Foo:
a: int
b: Bar
@property
def c(self):
return self.a + self.b.x - self.b.y
Run Code Online (Sandbox Code Playgroud)
我可以按如下方式序列化数据结构:
class CustomEncoder(json.JSONEncoder):
def default(self, o):
if dataclasses and dataclasses.is_dataclass(o):
return dataclasses.asdict(o)
return json.JSONEncoder.default(self, o)
foo = Foo(1, Bar(2,3))
print(json.dumps(foo, cls=CustomEncoder))
# Outputs {"a": 1, "b": {"x": 2, "y": 3}}
Run Code Online (Sandbox Code Playgroud)
但是,我还想序列化属性 ( …
python serialization immutability python-3.x python-dataclasses
目前,我试图理解Scala中的功能编程,我遇到了一个我无法弄清楚的问题.
想象一下以下情况:
你有两个类:Controller和Bot.甲博特是由一个启动的独立演员控制器,做一些昂贵的操作,并将结果返回到控制器.因此,控制器的目的很容易描述:实例化Bot的多个对象,启动它们并接收结果.
到现在为止还挺好; 我可以在不使用任何可变对象的情况下实现所有这些.
但是我该怎么做,如果我必须存储Bot返回的结果,以后再用作另一个Bot的输入(后来意味着我不知道什么时候在编译时!)?
使用可变列表或集合执行此操作相当容易,但我在代码中添加了许多问题(因为我们在这里处理并发).
遵循FP范例,是否可以通过安全地使用不可变对象(列表...)来解决这个问题?
顺便说一句,我是FP新手,所以这个问题可能听起来很愚蠢,但我无法弄清楚如何解决这个问题:)
正如我所知,Haskell中的变量是不可变的(因此,它们实际上不是"变量").
在这种情况下,如果我们有一个复杂的大数据结构,如红黑树,我们应该如何实现实际改变数据结构的操作?
每次插入或删除元素时都创建树的副本?
我有一个返回Map的方法.我最初会返回该方法生成的HashMap,但认为返回一个ImmutableMap会更好.不幸的是,以下语句拒绝在eclipse中工作:
HashMap<File, File> map = new HashMap<File, File>();
map.put(...);
.
.
.
return ImmutableMap.builder ().putAll (map).build ();
Run Code Online (Sandbox Code Playgroud)
它一直在说我正在回复一个不相容的陈述,a Map<Object, Object>.
我最初尝试使用:
return ImmutableMap<File, File>.builder ().putAll (map).build ();
Run Code Online (Sandbox Code Playgroud)
但这显然不起作用.我最好如何解决这个问题?我应该先将它存储在类似的东西中
ImmutableMap<File, File> m = ImmutableMap.builder ().putAll (map).build ();
Run Code Online (Sandbox Code Playgroud)
还是有更优雅的解决方案?
immutability ×10
java ×4
collections ×2
final ×2
python ×2
scala ×2
string ×2
c# ×1
c++ ×1
clojure ×1
guava ×1
haskell ×1
mutable ×1
python-3.x ×1