标签: immutability

readonly是否有任何运行时开销?

出于某种原因,我一直认为readonly字段有与它们相关的开销,我认为这是CLR跟踪readonly字段是否已经初始化.这里的开销是一些额外的内存使用量来跟踪状态并在分配值时进行检查.

也许我假设这是因为我不知道一个readonly字段只能在构造函数内或字段声明本身内初始化,并且没有运行时检查,你将无法保证它不被多次分配给各种方法.但是现在我知道了,它可以很容易地被C#编译器静态检查,对吧?那是这样的吗?

另一个原因是,我已经读过使用readonly具有"轻微"性能影响,但他们从未涉及此声明,我无法找到有关此主题的信息,因此我的问题.我不知道除了运行时检查之外还有什么其他性能影响.

第三个原因是我看到它readonly在编译的IL 中被保留为initonly,所以这个信息在IL中的原因readonly是什么,如果只是C#编译器的保证,该字段永远不会分配给构造函数或声明?

另一方面,我发现你可以在readonly int没有CLR抛出异常的情况下设置通过反射的值,如果readonly是运行时检查则不可能.

所以我的猜测是:'readonlyness'只是一个编译时功能,任何人都可以确认/否认这个吗?如果是,那么这些信息被包含在IL中的原因是什么?

c# performance readonly immutability

18
推荐指数
2
解决办法
2339
查看次数

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

具有ArrayList成员变量的不可变对象 - 为什么可以更改此变量?

我有一个包含各种成员变量的类.有一个构造函数,有getter方法,但没有setter方法.实际上,这个对象应该是不可变的.

public class Example {
   private ArrayList<String> list; 
}
Run Code Online (Sandbox Code Playgroud)

现在我注意到以下内容:当我使用getter-method获取变量列表时,我可以添加新值等等 - 我可以更改ArrayList.当我下次get()为此变量调用时,将ArrayList返回更改的变量.怎么会这样?我没有再设置它,我只是努力了!有了String这种行为是不可能的.那么这里的区别是什么?

java object member immutability getter-setter

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

可变和不可变类型背后的理论是什么?

我钦佩Python的一个原因是它区分了可变类型和不可变类型.在进入Python之前花了一段时间在c编程,我很惊讶Python如何轻松地消除指针解除引用的所有复杂性,这让我很生气.在Python中,一切都按照我期望的方式工作,我很快意识到可变/不可变的区别在其中起着重要作用.

当然还有一些皱纹(可变函数参数默认是一个值得注意的例子)但总的来说,我觉得可变/不可变的区别大大澄清了变量及其值什么以及它们应该如何表现的问题.

但是它来自哪里?我必须假设GvR不是第一个设想这种区别的人,并且Python不是第一个使用它的语言.我有兴趣听听使用这个概念的早期语言,以及任何早期的理论讨论.

python language-theory mutable immutability

18
推荐指数
3
解决办法
1930
查看次数

是否可以在Hibernate/JPA中使用不可变字段?

在我们的应用程序中,我们需要只能分配一次的字段.

起初我们考虑封装字段并使setter私有化.但是,有些问题会引起:

  • 如果没有公共设置器,Hibernate是否仍能从数据库中映射字段?
  • 我可以剥离setter并仅在实体构造函数中使字段可变吗?
  • 最后,是否有任何标准的JPA方法使字段不可变?

提前致谢.

java hibernate immutability jpa-2.0

18
推荐指数
2
解决办法
1万
查看次数

使用不可变/持久类型和数据结构的并发是如何工作的?

我最近读了很多关于函数式语言的文章.由于那些只使用不可变结构,因此他们声称并发问题得到了极大改善/解决.我在理解如何在真实环境中实现这一点时遇到了一些麻烦.让我们假设我们有一个网络服务器,其中一个线程正在监听端口(好吧,IO是另一件我难以绕过头脑的东西,但现在让我们忽略它); 在任何连接尝试中,创建套接字并将其传递给新创建的线程,该线程对其进行一些操作,并且根据接收的通信,可以将更改应用于对服务器应用程序是全局的大列表/数据结构.那么,这个列表访问如何工作,以便所有线程具有一致的列表视图(或者至少为了在线程以正确的方式死亡时将一个线程所做的所有更改应用于列表) ?

我的理解问题是:

  • 显然,任何线程都可以获得列表的不可更改的"快照".但是,在通过创建应用了更改的列表的新版本来"更改"内容之后,我们仍然留下每个线程都有自己的列表版本.这些如何合并在一起?
  • 另一种方法可能包括使用传统的锁定机制,如互斥/ cond或go-like-channels.但是,当所有变量都是不可变的时候,你甚至会怎样创建这样的东西?
  • 我听说过STM,但不能处理副作用(即列表是否也会透明地将数据备份到文件或db)

那么你如何用函数式语言模拟这样的东西呢?

functional-programming immutability

18
推荐指数
1
解决办法
2576
查看次数

在操纵不可变数据结构时,Clojure的assoc-in和Haskell镜头之间有什么区别?

我需要操作和修改深层嵌套的不可变集合(映射和列表),我想更好地理解不同的方法.这两个库解决了或多或少相同的问题,对吧?它们有何不同,哪种类型的问题更适合另一种?

Clojure的assoc-in
Haskell'slens

haskell functional-programming clojure immutability haskell-lens

18
推荐指数
3
解决办法
1806
查看次数

Swift"可变"字符串真的可变,还是像Java字符串一样?

Swift编程语言中,在字符串部分String Mutability一节中,它说:

String可以通过将特定分配给变量(在这种情况下可以修改)或常量(在这种情况下不能修改)来指示特定是否可以修改(或变异):

并给出示例代码:

var variableString = "Horse"
variableString += " and carriage"
// variableString is now "Horse and carriage"

let constantString = "Highlander"
constantString += " and another Highlander"
// this reports a compile-time error - a constant string cannot be modified”
Run Code Online (Sandbox Code Playgroud)

这本书中的iBooks 这里,或在Web浏览器在这里.

在下一段中,它声称"字符串是值类型".

我的问题:对我来说,这看起来不像是一个可变的字符串.它看起来像我在Java(或C#,Python和其他)中习惯的:具有可变变量绑定的不可变字符串对象.换句话说,有一个对象"Horse",然后它创建了一个新的String对象"Horse and carriage"并将其设置为相同的变量.而且由于无法区分对不可变对象的引用与值类型(对吗?)之间的区别,我想知道:为什么他们这样描述它?这些Swift字符串与它在Java中的方式有​​什么区别吗?(或C#,Python,Objective-C/NSString)

string immutability swift

18
推荐指数
2
解决办法
1万
查看次数

按字母顺序immutable.js排序

我想按属性对immutable.js orderedList进行排序name,

data.map(x => x.get("name")) 返回字符串,我想按字母顺序按名称对地图进行排序.

怎么做?我试过了:

return data.sortBy((val) => {
    if (dir === "up") {
      return val.get("name");
    } else {
      return - val.get("name");
    }
  });
Run Code Online (Sandbox Code Playgroud)

javascript immutability immutable.js

18
推荐指数
1
解决办法
2万
查看次数

Kotlin:延迟到val,或者是一个可以设置一次的var

只是好奇:在Kotlin中,我很想得到一些可以通过懒惰来初始化的val,但是有一个参数.那是因为我需要为了初始化它而创建的东西很晚.

具体来说,我希望我有:

private lateinit val controlObj:SomeView
Run Code Online (Sandbox Code Playgroud)

要么:

private val controlObj:SomeView by lazy { view:View->view.findViewById(...)}
Run Code Online (Sandbox Code Playgroud)

然后:

override fun onCreateView(....) {
    val view = inflate(....)


    controlObj = view.findViewById(...)
Run Code Online (Sandbox Code Playgroud)

或在第二种情况下controlObj.initWith(view)或类似的情况:

return view
Run Code Online (Sandbox Code Playgroud)

我无法使用,by lazy因为by lazy初始化时不会接受外部参数.在这个例子中 - 包含view.

当然我有,lateinit var但如果我能确保它在设置后变为只读,我会在一行中完成它会很好.

是否有一种非常干净的方法来创建只读初始化一次的只读变量,但只有当其他变量出生时?任何init once关键字?在init之后,编译器知道它是不可变的?

我知道这里存在潜在的并发问题,但如果我敢于在init之前访问它,我当然应该被抛出.

android immutability lazy-evaluation kotlin kotlin-lateinit

18
推荐指数
3
解决办法
6845
查看次数