[Rust] 러스트 프로그래밍 공부 변수와 상수, 섀도잉

반응형

1. 러스트 변수(Rust Variables)

- 변수는 기본적으로 불변(immutable)이나, 필요에 따라 변수를 가변(mutable)로 만들 수 있다. 변수가 불변일 때, 어떤 이름에 한번 값이 묶이면 그 값은 바꿀 수 없다. 이를 테스트하기 위해 workspace 안에 variables라는 프로젝트를 만들어 보자.

cargo new variables // variables 라는 프로젝트 생성

cd variables/src // variables 디렉토리로 이동

vi main.rc // src 디렉토리 내 main.rc 파일을 열어 코드 편집

 

아래의 프로그램을 작성하고 cargo run 명령어로 프로그램을 실행해보자. 

fn main() {
    let x = 5;
    println!("The value of x is : {x}");
    x = 6;
    println!("The value of x is : {x}");
}

 

그럼 위의 오른쪽 이미지처럼 "cannot assign twice to immutable variable 'x'" 에러 메시지가 나타날 것이다.

처음 let x로 지정하면서 기본적으로 불변의 변수가 선언되는데, 이후 두 번째 값을 할당할 수 없기 때문에 발생하는 에러이다. 불변으로 지정한 값을 변경하려고 하는 이 상황이 버그로 이어질 수 있기 때문에 컴파일 에러가 발생하는 것은 매우 중요하다. (실제 디버깅할 때 정수로 지정된 변수를 사용하다 이후 커널 패치에 의해 양수만 사용할 수 있게 된 적이 있었는데, 이전에 -1 값을 사용해서 버그가 생겼던 적이 있었다. 디버깅할 때 고생 꽤 했다..)

 

그래서 변수를 mut로 지정해서 해당 변수가 가변이 될 수 있다고 알려주는 것은 가변성과 코드 작성에 유연함과 편안함을 준다. (추후 이 코드를 볼 사람들에게 이 변수는 값이 변할 것이라는 의도를 전달하는 것이다.)

 

위 코드에서 let x = 5; 라고 적은 부분을 let mut x = 5; 라고 수정해준 뒤, cargo run 명령어를 통해 실행하면 아래처럼 프로그램이 정상적으로 실행되는 것을 볼 수 있다. 가변성을 사용할지 말지는 코드를 짜는 사람의 몫이고, 특정 상황에서 해당 변수가 어떻게 쓰일지, 어떻게 쓰는 것이 가장 명확할지에 따라 달라진다.


2. 러스트 상수 (Rust constant)

상수(constant)는 값을 바꿀 수 없고, mut 와 함께 사용한다. 상수는 let 키워드 대신 const 키워드로 선언하며, 값의 타입은 반드시 명시되어야 한다. 상수는 전역 스코프를 포함한 어떤 스코프에서도 선언 가능하고, 반드시 상수 표현식으로만 설정될 수 있도록 한다. 러스트의 이름 짓기 관례에서 상수는 단어와 단어 사이에는 밑줄을 사용하고, 모든 글자는 대문자로 쓴다. 상수는 선언된 스코프 내에서 프로그램이 작동하는 전체 시간 동안 유효하다.

 

const THREE_HOURS_IN_SECONDS: u32 = 6o * 60 * 3;

 

3. 섀도잉

러스타시안들은 첫 번째 변수가 두 번째 변수에 의해 가려졌다(shadowed)는 의미에서 섀도잉 이라는 표현을 쓴다. (이는 해당 변수의 이름을 사용할 때 컴파일러가 두 번째 변수를 보게 될 것이라는 의미이다.) 두 번째 변수는 첫 번째 변수를 가려서, 스코프가 끝날 때까지 변수명의 사용을 가져간다. 쉽게 이해하기 위해 아래의 코드를 보자.

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 ix {x}");
    
}

 

위 코드에서 x에 5라는 값을 먼저 바인딩한다. 그 다음 let x = 을 반복해서 새로운 변수 x를 만들고, 원래 값에 1을 더한 값을 대입해서 x의 값은 6이 된다. 그 후 중괄호 안쪽 스코프 내에 있는 세 번째 let 구문 또한 x를 가리고 새로운 변수를 만드는데, 이전 값에 2를 곱해 x 에 할당하여 최종값은 12가 된다. 이 스코프가 끝나면 안쪽의 섀도잉은 끝나서 x는 다시 6으로 돌아온다.

 

섀도잉은 변수를 mut로 표시하는 것과는 다르다. let을 사용하면, 값을 변형하면서 변형이 완료된 후에는 불변으로 유지할 수 있다.

mut와 섀도잉의 또 다른 차이점은 let 키워드를 사용하여 새로운 변수를 만드는 것이기 때문에 같은 변수명으로 다른 타입의 값을 저장할 수 있다는 것이다.

 

let spaces = "    ";
let spaces = spaces.len();

 

 첫 번째 spaces는 문자열 타입이고 두 번째 spaces는 숫자 타입이다. 따라서 섀도잉은 spaces_str과 spaces_num과 같이 구분되는 변수명을 쓸 필요가 없다. 즉, 더 간단한 spaces 라는 이름을 재사용할 수 있게 해준다. 아래와 같이 mut를 사용해서 동일한 변수명을 사용하면 컴파일 에러가 발생하니 참고!

let mut spaces = "    ";
spaces = spaces.len();
반응형