Затенение переменных (shadowing)
Кратко
В Rust, если переменная (let или let mut) a повторно объявляется позже, такое поведение называется shadowing.
- константу
constнельзя затенять (shadowing) - shadowing может действовать в области видимости блока (
{}) - shadowing позволяет при том же имени переменной объявить новый тип данных
Источник
https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {}", x);
}
println!("The value of x is: {}", x);
}
Эта программа сначала связывает x со значением 5. Затем она затеняет x, повторяя let x =: берётся исходное значение, к нему прибавляется 1, и x становится 6. Затем во внутренней области видимости третий оператор let снова затеняет x, умножая предыдущее значение на 2, так что x получает значение 12. Когда эта область видимости заканчивается, внутреннее затенение прекращается, и x снова равен 6. При запуске этой программы будет выведено следующее:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
Finished dev [unoptimized + debuginfo] target(s) in 0.31s
Running `target/debug/variables`
The value of x in the inner scope is: 12
The value of x is: 6
Shadowing отличается от объявления переменной как mut: если мы случайно попытаемся присвоить этой переменной новое значение без ключевого слова let, мы получим ошибку времени компиляции. Используя let, мы можем выполнить несколько преобразований значения, но после их завершения переменная остаётся неизменяемой.
Другое отличие mut от shadowing состоит в том, что при повторном использовании ключевого слова let мы фактически создаём новую переменную, поэтому можем изменить тип значения, сохранив то же имя. Например, пусть программа просит пользователя указать, сколько пробелов он хочет между словами, вводя символы пробела, но мы хотим сохранить этот ввод как число:
let spaces = " ";
let spaces = spaces.len();
Такая конструкция допустима, потому что первая переменная spaces имеет строковый тип, а вторая переменная spaces — совершенно новая переменная, которая просто совпадает по имени с первой, — имеет числовой тип. Таким образом, shadowing избавляет нас от необходимости придумывать разные имена вроде spaces_str и spaces_num; вместо этого мы можем повторно использовать более простое имя spaces. Однако если мы попробуем использовать для этого mut, как показано ниже, мы получим ошибку времени компиляции:
let mut spaces = " ";
spaces = spaces.len();
Ошибка гласит, что менять тип переменной нельзя:
$ cargo run
Compiling variables v0.1.0 (file:///projects/variables)
error[E0308]: mismatched types
--> src/main.rs:3:14
|
3 | spaces = spaces.len();
| ^^^^^^^^^^^^ expected `&str`, found `usize`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `variables` due to previous error