러스트 변수
목차
러스트의 공식 튜토리얼인 The Rust Programming Language를 참고하는 기초 튜토리얼 두번째 포스팅입니다.
러스트는 초보자들에게 추천하는 언어는 아닙니다. 러스트 기초에서 나오는 개념들도 프로그래밍 언어의 기초를 배우지 않았다면 좀 이해하기 어렵습니다. 이 포스팅 시리즈에서도 컴퓨터 공학의 기본 개념을 어느 정도는 알아듣는다는 전제로 설명하기 때문에 참고하시길 바랍니다.
인터넷적으로 보면 러스트는 서버사이드(백엔드) 언어입니다. 초보자들이 백엔드를 시작한다면 Python, Java, C# 같은 언어를 먼저 배우는 것이 좀 더 나을 수 있습니다. 시스템 프로그래밍이라면 리눅스에서 배우는 C언어가 좋습니다.
가변성(Mutability)
러스트 변수와 가변성이라는 주제로 시작해보겠습니다. 가변성(mutability)이란 단어가 기존 언어들과는 다른 생소한 느낌이 들지 모르겠습니다.
변수가 당연히 가변성이 있지 않냐? 고 말할 수 있는데 러스트에서 변수는 기본적으로 불변성(immutable)을 가집니다. 무슨말이냐면 let으로 변수를 선언하면 바꿀 수 없다는 뜻 입니다. 다음 러스트 코드를 컴파일하면 오류가 납니다. let은 변수를 선언하는 키워드입니다.
fn main() { let a = 5; println!("a : {}", a); a = 4; println!("a : {}", a); }
이상하게도 변수인데 a에 값을 두번 할당할 수가 없습니다. 그럼 상수아닌가? 라는 생각이 듭니다. C언어에서는 const 로 상수를 만들었는데 이건 기본 변수가 상수화가 되어 있습니다.
오류 메시지를 보면 cannot assign twice to immutable variable 라고 나와있습니다. 불변성 변수에 두번 값이 할당할 수 없다는 말입니다. 필자도 처음 저 오류 메시지를 봤을 때 어리둥절 했습니다. 변수에 값을 할당할 수 없는데 그게 무슨 변수냐? 라고 할 수 있지만 이것이 러스트의 기본 시스템입니다. 어떤 메모리에 값을 쓰면 기본은 변하지 않는 값이다.
그럼 값을 변하게 할려면 어떻게 해야하는가? 다음과 같이 변수 선언시 mut (mutable의 약자)를 붙여주면 됩니다.
fn main() { let mut a = 5; println!("a : {}", a); a = 4; println!("a : {}", a); }
상수(Constants)
immutable 인 변수를 상수처럼 사용하면 좋겠지만 당연히 상수도 필요합니다. 러스트에서 상수와 변수의 차이점은 mut 의 사용여부입니다. 상수 키워드 const 에는 mut는 사용이 불가합니다. 상수는 항상 불변합니다.(immutable) 또 상수는 데이터 타입을 명시해야 합니다.
이런 부분들이 동적타이핑(dynamic typing) 언어에만 익숙한 사람들에게는 조금 쉽지 않겠지만 C계열의 정적타이핑 언어로 개발한 경험이 있다면 이해가 쉬울 것 입니다.
다음 코드는 상수를 선언하고 사용합니다. 아직 데이터 타입을 배우지 않았으니 u32는 모를 수 있습니다. 그보다 일단 const의 형식에 주목합니다.
fn main() { const ONE_HOUR_IN_SECONDS: u32 = 60*60; println!("1시간은 몇초? : {}", ONE_HOUR_IN_SECONDS); }
const 키워드가 붙은 상수에 값을 할당하려고 하면 다음과 같은 오류 메시지가 나옵니다. cannot assign to this expression 표현식에 할당이 불가능하다 – 계속 반복인데 상수는 처음 한번 말고 그 다음에 값이 할당이 불가능합니다.
또 한가지는 상수를 선언하는 방법입니다. 60 * 60 의 표현식을 사용할 수 있습니다. 표현식에는 허용범위가 있으니 참고합니다. 상수는 스코프가 살아있으면 런타임에서 계속 유지됩니다. 전역 스코프에서 사용하면 프로그램이 끝까지 유지시켜야 하는 값으로 사용가능합니다.
Shadowing (쉐도잉)
쉐도잉은 그림자처럼 가린다는 뜻입니다. 다음 예시를 보면 let 키워드를 같은 변수에 두번 사용하고 있습니다. let 은 immutable 이라고 했는데 여기서는 또 바꿀 수가 있습니다. let 키워드를 한번 더 쓰면 가능합니다.
fn main() { let _shadow = 3; let _shadow = 7; println!("shadow value : {}", _shadow); }
쉐도잉은 데이터 타입도 바꿀 수 있습니다. 아래 예시를 보면 문자열 “string”을 숫자 6으로 바꿀 수 있습니다. mut 키워드로는 타입 변경 에러(mismatched types)가 발생합니다.
fn main() { let _shadow = "string"; let _shadow = "string".len(); println!("shadow value : {}", _shadow);
요약
러스트 변수, 가변성, 상수에 대해 알아봤습니다. 이 개념들이 처음에 헷갈릴 수 있습니다만, 그렇게 어려운 내용은 아닙니다. 변수에 대해서 감을 잡았다면 다음은 데이터 타입에 대해서 알아볼 차례입니다.