Constants in C++ and Rust are fundamentally different. In C++ constness is a property of any type, while in Rust it is a property of a reference. Thus, in Rust there are not true constant types.
Take for example this C++ code:
void test() {
const std::string x;
const std::string *p = &x;
const std::string &r = x;
}
Variable x
is declared of constant type, so any reference created to it will be also to constant, and any attempt to modify it (with const_cast
for exampe) will render undefined behavior. Note how const
is part of the type of the object.
In Rust, however, there is no way to declare a constant variable:
fn test() {
let x = String::new();
let r = &x;
let mut x = x; //moved, not copied, now it is mutable!
let r = &mut x;
}
Here, the const-ness or mut-ness is not part of the type of the variable, but a property of each reference. And even the original name of the variable can be considered a reference.
Because when you declare a local variable, either in C++ or Rust, you are actually doing two things:
- Creating the object itself.
- Declaring a name to access the object, a reference of sorts.
When you write a C++ constant you are making both constant, the object and the reference. But in Rust there are no constant objects, so only the reference is constant. If you move the object you dispose the original name and bind to a new one, that may or may not be mutable.
Note that in C++ you cannot move a constant object, it will remain constant forever.
About having two consts
for pointers, they are just the same in Rust, if you have two indirections:
fn test() {
let mut x = String::new();
let p: &mut String = &mut x;
let p2: &&mut String = &p;
}
About what is better, that is a matter of taste, but remember all the weird things that a constant can do in C++:
- A constant object is always constant, except when it is not: constructors and destructors.
- A constant class with mutable members is not truly constant.
mutable
is not part of the type system, while Rust's Cell/RefCell
are.
- A class with constant member is a pain to work with: default constructors and copy/move operators do not work.
mut
there to indicate mutability? – Silberconst int& const
is it that what you are missing? – Silberconst
s in C++ for references) and the C++ example is about pointers – Silberconst
associated with the & operator just refers to whether the data it is bound to isconst
. – Photophore