Compile-time constants (const) can be declared in the local scope as well as the global scope.
In the local scope, I think that typically let statements would be used.
Are there any advantages to using const instead of let in the local scope?
In short, instead of the following code using let in the local scope:
let foo = "Hello, world!";
println!("{foo}");
assert_eq!(foo.len(), 13);
Are there any advantages to the following code which uses const?
Depends on what you mean by "advantage." If you're taking about performance, they should be the same. Semantically though, a const means something different and is guaranteed not to change. A let variable can be shadowed, like this:
fn main() {
let foo = "hello";
let foo = "world";
let foo = 42;
}
If you tried the same with constants, that's an error.
Should we use let statements ​​unless we "really" need the guarantee that the value is immutable? In this case, if let and const have the same performance, I think let is more convenient.
Honestly, I think it comes down to preference. Personally I like using const for things that feel like constants. If I had a function calculating acceleration, I would specify g as a const instead of a variable.
fn falling_velocity(t: f32) -> f32 {
const G: f32 = 9.8;
0.5 * G * t * t
}
If any other functions end up needing my constant in the future, it's as easy as cutting it out of the function and putting it in the outer scope.
Besides being usable in places that only constants are given, another characteristic of constants is that if there is some computation to be performed to determine the value of the constant, then that computation will happen at compile time.
fn foo() -> u32 {
const K: u32 = {
let mut x = 1;
while !(x % 2 == 0 && x % 3 == 0 && x % 5 == 0) {
x += 1;
}
x
};
K
}
Here, the while loop will definitely be executed at cargo build time and not every time foo() is called.
Generally, the optimizer may be able to perform “constant folding”, replacing computations with their results, on other expressions not in a const; but this is limited and generally won’t execute an arbitrary algorithm with loops.
Note that a const can't be shadowed only because it's an "item", like statics and structs, and items in general cannot be shadowed. It has nothing to do with const being a "constant".
That said, a const does not represent "a variable that does not change", but rather it's an alias for a compile time constant value.