Shadowing은 동일한 스코프 내에서 변수를 여러 번 선언할 수 있는 기능으로, 새로운 변수가 이전 변수를 "가립니다". shadowing이 없는 언어(C, C++)에서는 변수를 다시 정의하면 오류가 발생하거나 정의되지 않은 동작이 발생합니다. Rust는 shadowing을 허용하며 각 변수는 새로운 타입이나 값으로 독립적인 객체입니다. 이는 값의 단계적 변환을 수행하는 데 유용합니다. 예를 들어, 문자열을 바로 숫자로 변환할 때 새로운 이름을 만들지 않아도 됩니다.
문제: 한편으로는 가독성이 향상되고 변수 이름의 비대화를 방지하지만, 다른 한편으로는 복잡한 블록에서 변수를 실수로 "가리는" 경우 디버깅이 어려워져 예상치 못한 결과를 얻게 됩니다.
해결책: Shadowing은 실제로 변환을 쉽게 하고 가독성을 해치지 않는 곳에서만 사용해야 합니다. 각 "let var = ...;"는 새로운 변수를 생성하며, 이전 변수는 선언 블록 외부에서 변경되지 않습니다.
코드 예시:
fn example() { let x = "42"; let x = x.parse::<i32>().unwrap(); println!("x: {}", x); // x: 42 }
주요 특징:
Shadowing이 변수를 가변적으로 변경할 수 있습니까?
네, 불변 변수를 가변 변수로 가리킬 수 있습니다:
let x = 5; let mut x = x; x += 1;
Shadowing이 이전 변수를 파괴한다고 의미합니까?
아니요, 이전 변수의 값은 선언된 블록이 끝날 때까지 살아있지만 이름으로는 접근할 수 없습니다.
루프나 중첩 블록 내에서 shadowing을 사용할 수 있습니까?
네, 각 스코프는 동일한 이름으로 변수를 선언할 수 있으며, 이는 다른 변수가 됩니다.
함수 내에 let result = expr1; ... let result = expr2;이 있어 타입이 다릅니다.
장점:
단점:
타입 변경을 위해서만 shadowing을 사용합니다: 먼저 문자열을 파싱하고, 이후 숫자 할당.
장점:
단점: