프로그래밍Rust 개발자

Rust에서 'shadowing' (변수 가리기)은 어떻게 작동합니까? 이 메커니즘의 장점은 무엇이며, 어떤 문제가 발생할 수 있으며, 실제로 올바르게 사용하는 방법은 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

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은 가변성과 다릅니다: shadowing을 위해 가변성이 필요하지 않습니다.

트릭 질문들.

Shadowing이 변수를 가변적으로 변경할 수 있습니까?

네, 불변 변수를 가변 변수로 가리킬 수 있습니다:

let x = 5; let mut x = x; x += 1;

Shadowing이 이전 변수를 파괴한다고 의미합니까?

아니요, 이전 변수의 값은 선언된 블록이 끝날 때까지 살아있지만 이름으로는 접근할 수 없습니다.

루프나 중첩 블록 내에서 shadowing을 사용할 수 있습니까?

네, 각 스코프는 동일한 이름으로 변수를 선언할 수 있으며, 이는 다른 변수가 됩니다.

일반적인 오류 및 안티 패턴

  • 서로 다른 타입으로 shadowing하여 가독성을 떨어뜨림
  • 깊은 중첩에서 변수를 실수로 "가리기"
  • 값만 바꾸기 위해 shadowing을 사용하는 것(더 나은 방법은 가변성임)

현실 사례

부정적인 케이스

함수 내에 let result = expr1; ... let result = expr2;이 있어 타입이 다릅니다.

장점:

  • 변환에서 편리함

단점:

  • 읽기 어렵고 디버깅 시 실수할 위험이 있음

긍정적인 케이스

타입 변경을 위해서만 shadowing을 사용합니다: 먼저 문자열을 파싱하고, 이후 숫자 할당.

장점:

  • 명확하게 변수가 변환 단계를 반영함

단점:

  • 부주의할 경우 큰 함수에서 컨텍스트를 잃음