出于某种原因,我一直认为readonly字段有与它们相关的开销,我认为这是CLR跟踪readonly字段是否已经初始化.这里的开销是一些额外的内存使用量来跟踪状态并在分配值时进行检查.
也许我假设这是因为我不知道一个readonly字段只能在构造函数内或字段声明本身内初始化,并且没有运行时检查,你将无法保证它不被多次分配给各种方法.但是现在我知道了,它可以很容易地被C#编译器静态检查,对吧?那是这样的吗?
另一个原因是,我已经读过使用readonly具有"轻微"性能影响,但他们从未涉及此声明,我无法找到有关此主题的信息,因此我的问题.我不知道除了运行时检查之外还有什么其他性能影响.
第三个原因是我看到它readonly在编译的IL 中被保留为initonly,所以这个信息在IL中的原因readonly是什么,如果只是C#编译器的保证,该字段永远不会分配给构造函数或声明?
另一方面,我发现你可以在readonly int没有CLR抛出异常的情况下设置通过反射的值,如果readonly是运行时检查则不可能.
所以我的猜测是:'readonlyness'只是一个编译时功能,任何人都可以确认/否认这个吗?如果是,那么这些信息被包含在IL中的原因是什么?
两者有什么区别?
是否应该在一个实体上使用一个或两个?
我有一个包含各种成员变量的类.有一个构造函数,有getter方法,但没有setter方法.实际上,这个对象应该是不可变的.
public class Example {
private ArrayList<String> list;
}
Run Code Online (Sandbox Code Playgroud)
现在我注意到以下内容:当我使用getter-method获取变量列表时,我可以添加新值等等 - 我可以更改ArrayList.当我下次get()为此变量调用时,将ArrayList返回更改的变量.怎么会这样?我没有再设置它,我只是努力了!有了String这种行为是不可能的.那么这里的区别是什么?
我钦佩Python的一个原因是它区分了可变类型和不可变类型.在进入Python之前花了一段时间在c编程,我很惊讶Python如何轻松地消除指针解除引用的所有复杂性,这让我很生气.在Python中,一切都按照我期望的方式工作,我很快意识到可变/不可变的区别在其中起着重要作用.
当然还有一些皱纹(可变函数参数默认是一个值得注意的例子)但总的来说,我觉得可变/不可变的区别大大澄清了变量及其值是什么以及它们应该如何表现的问题.
但是它来自哪里?我必须假设GvR不是第一个设想这种区别的人,并且Python不是第一个使用它的语言.我有兴趣听听使用这个概念的早期语言,以及任何早期的理论讨论.
在我们的应用程序中,我们需要只能分配一次的字段.
起初我们考虑封装字段并使setter私有化.但是,有些问题会引起:
提前致谢.
我最近读了很多关于函数式语言的文章.由于那些只使用不可变结构,因此他们声称并发问题得到了极大改善/解决.我在理解如何在真实环境中实现这一点时遇到了一些麻烦.让我们假设我们有一个网络服务器,其中一个线程正在监听端口(好吧,IO是另一件我难以绕过头脑的东西,但现在让我们忽略它); 在任何连接尝试中,创建套接字并将其传递给新创建的线程,该线程对其进行一些操作,并且根据接收的通信,可以将更改应用于对服务器应用程序是全局的大列表/数据结构.那么,这个列表访问如何工作,以便所有线程具有一致的列表视图(或者至少为了在线程以正确的方式死亡时将一个线程所做的所有更改应用于列表) ?
我的理解问题是:
那么你如何用函数式语言模拟这样的东西呢?
我需要操作和修改深层嵌套的不可变集合(映射和列表),我想更好地理解不同的方法.这两个库解决了或多或少相同的问题,对吧?它们有何不同,哪种类型的问题更适合另一种?
haskell functional-programming clojure immutability haskell-lens
在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)
在下一段中,它声称"字符串是值类型".
我的问题:对我来说,这看起来不像是一个可变的字符串.它看起来像我在Java(或C#,Python和其他)中习惯的:具有可变变量绑定的不可变字符串对象.换句话说,有一个对象"Horse",然后它创建了一个新的String对象"Horse and carriage"并将其设置为相同的变量.而且由于无法区分对不可变对象的引用与值类型(对吗?)之间的区别,我想知道:为什么他们这样描述它?这些Swift字符串与它在Java中的方式有什么区别吗?(或C#,Python,Objective-C/NSString)
我想按属性对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) 只是好奇:在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之前访问它,我当然应该被抛出.
immutability ×10
java ×3
hibernate ×2
android ×1
c# ×1
clojure ×1
entity ×1
haskell ×1
haskell-lens ×1
immutable.js ×1
javascript ×1
jpa ×1
jpa-2.0 ×1
kotlin ×1
member ×1
mutable ×1
object ×1
performance ×1
python ×1
readonly ×1
string ×1
swift ×1