为什么scala没有C++ - 就像const-semantics?

tst*_*ner 20 c++ types scala const

在C++中.我可以将大多数事物声明为const,例如:
变量:const int i=5;
Scala有val i=5,但是这只会阻止重新分配,而不是更改对象,如下例所示:
C++:

const int i[]={1,2,3,4};
i[2]=5; //error
Run Code Online (Sandbox Code Playgroud) 斯卡拉:
val a=Array(1,2,3,4)
a(2)=5 //a is now Array(1, 2, 5, 4)

使用成员函数会更糟:
C++:

class Foo {
int i;
int iPlusFive() const {return i+5;}
int incrementI(){ return ++i; }
}
我可以肯定,调用iPlusFive不会改变对象,我不会在const对象上不小心调用incrementI.

当涉及到集合时,C++继续使用const集合的const-correct条纹:简单地将你的向量声明为const而你无法改变它.将a分配non-const vector<Int>给a const vector<Int>,编译器不会复制任何内容,并且会阻止您更改now const集合中的任何内容.

Scala有scala.collection.mutable.whatever和scala.collection.immutable.whatever,你不能只将可变集合转换为不可变集合,而且你仍然可以用非const成员函数更改收集的对象.

为什么scala,它有一个非常好的类型系统,没有任何可比的C++ const-keyword?

编辑: Margus建议使用import scala.collection.mutable.我的解决方案是使用

import scala.collection.mutable.HashMap
import scala.collection.immutable.{HashMap => ConstHashMap}
Run Code Online (Sandbox Code Playgroud) 这将使可变HashMap可用作HashMap和不可变的als ConstHashMap,但我仍然更喜欢C++方法.

Sil*_*man 10

我不喜欢C++ const逻辑的是它是关于引用而不是引用的对象.如果我有一个"const T*",则无法保证持有非const指针的人不会修改对象的状态.因此,它无论如何都无助于避免多线程系统中的竞争条件,也无助于实现持久性容器.

在我看来,拥有一个不可变类的概念并且在标准库中缺少不可变容器是任何语言中的错误是非常有帮助的.由于这些应该具有可观察的不变性,但由于效率原因可能需要能够改变内部/不可见状态,我认为const语法几乎没有帮助.

Scala具有我们需要直接使用或基于其他不可变类的不可变类.这非常有价值.额外的语法可能是一个很好的补充,但我可以没有它.


xan*_*xan 6

因为C++ const在复杂系统中并不那么好.

我可以肯定,调用iPlusFive不会改变对象,我不会在const对象上不小心调用incrementI.

不,你不能,因为实现(可能在图书馆某处看不到的地方)可以抛弃常量.如果没有const,其他语言必须以更安全的方式强制执行不变性(例如,请参阅@ Margus的答案中的Collections.unmodifiableList()).

Const只是编译器读取的文档.文档通常很有帮助,但有时会产生误导.

当涉及到集合时,C++继续使用const集合的const-correct条纹:简单地将你的向量声明为const而你无法改变它.

聚合是const常常让我崩溃的地方.例如,我经常要声明一个方法不会更改向量但可能会更改它的成员(或返回非const成员引用).我必须使所有const或所有nonconst或为每个组合发明新的类型变体.

'mutable'弥补了一些聚合问题,但引入了更多的复杂性和误用.


Vas*_*iuk 5

IMO,Scala提供了更大的灵活性,不会将引用的不变性与其背后的结构的可能的可变性混淆,使您能够做出设计决策WRT您正在处理的问题.

  • 我在谈论数据结构与引用的不变性,而不是数据结构与其内容.例如,您不能在不可变数据结构中添加/删除元素,而内容(单个元素)的变异是可能的. (5认同)