Rust 변수

Rust 변수

변수 선언

Rust에서 변수(variable)를 선언하기 위해서는 "let" 키워드를 사용한다.

let a = 100;   
let b = 3.14;  

변수의 데이타 타입이 정의되지 않는 경우 Rust 컴파일러는 타입을 추론하여 결정하게 된다. 예를 들어, 위 코드에서 a는 100 이라는 정수가 할당되는데 컴파일러는 디폴트로 (32비트 정수를 의미하는) i32 타입이라고 판단한다. 또한, 소숫점이 있는 숫자가 할당된 b의 경우, 컴파일러는 (64비트 double 타입인) f64 타입을 디폴트로 정의한다.

let c: u32 = 12345;
let d: f32  = 3.14;  
let e: bool = true;

변수의 데이타 타입을 명시적으로 지정하는 경우는 변수명 뒤에 콜론(:)을 찍고, 데이타 타입을 지정한다. 예를 들어, 위의 변수 c는 unsigned 32비트 정수를 의미하는 u32 타입을 지정한 것이고, 변수 d는 32비트 부동소수점 타입인 f32 타입, 그리고 변수 e는 부울린 타입 bool 을 지정한 것이다.

변수의 불변성 (Immutability)

Rust 프로그래밍 언어에서 모든 변수는 "디폴트로" 불변성(Immutability)의 성질을 갖는다. 불변성(Immutability)이란 변수에 값이 한번 지정된 후에는 그 값을 변경할 수 없는 특성을 말한다. 대다수의 다른 프로그래밍 언어들에 있어서 변수들은 디폴트로 가변적인(mutable) 특성을 가지는데, 이는 다시 말하면 변수의 값을 프로그램 실행 중 계속 변경할 수 있다는 것을 의미한다.

아래 예제를 보면, 변수 a에 처음 100을 할당한 후에, 다시 1을 증가시키려 하였는데, 이 프로그램은 컴파일러에 의해 에러로 처리된다. 즉, 런타임시에 에러가 나는 것이 아니라, 컴파일 싯점에 이미 에러를 잡아내는 것이다.

let a = 100;
a = a + 1;     // 에러: cannot assign twice to immutable variable `a`
println!("{}", a);

가변적 변수 : mut

변수의 데이타가 변경되어야 하는 경우에는, 변수 앞에 "mut" 라는 키워드를 지정한다. 예를 들어, 아래와 같이 변수 a를 mut로 지정하면, a의 값을 변경할 수 있다.

let mut a = 100;
a = a + 1;    // 에러 없음
println!("{}", a);

상수

Rust에서 상수(constant)는 항상 불변의 값을 갖는다. 상수는 (let 이 아닌) const로 선언되며, 항상 데이타 타입을 지정해야 한다. let으로 선언되는 변수의 경우 컴파일러가 추론(infer)을 통해 데이타 타입을 알아낼 수 있지만, 상수의 경우는 항상 타입을 지정해야 한다.

fn main() {
    const PI: f64 = 3.141592;

    let area = PI * 5.0 * 5.0;
    println!("{}", area);
}

Shadowing

Rust의 특별한 기능 중의 하나로 Shadowing 기능을 들 수 있다. Rust 코드에서 "let"은 변수를 선언하는데 사용되는데, 한 코드 Scope에서 동일한 변수명을 let으로 여러번 정의하는 것이 가능하다. 예를 들어, 아래 예제에서 변수 a는 처음에 정수 타입으로 선언되었는데, 중간에 let을 사용하여 변수 a를 다시 문자열 타입으로 변경하여 정의하였다. 다른 프로그래밍 언어에서 이러한 것을 허용하지 않지만, Rust에서는 이러한 기능을 허용하고 있으며, 이를 Shadowing 이라 부른다.

fn main() {
    let a = 1;        // 변수 a는 정수형
    println!("{}", a);

    let a = "hello";  // 변수 a는 문자열
    println!("{}", a);
}

Shadowing은 코드 중간에 변수타입과 값을 변경하게 되는데, 아래 코드의 경우 처음 변수 a가 i32 타입으로 1을 갖은 후, 두번째 라인에서 i32 타입인 변수 a가 되면서 2를 값에 할당한다. 이 싯점에 이전의 변수 a는 잊게 되고 2를 갖는 a만을 기억하게 된다.

fn main() {
    let a = 1;
    let a = 2;
    {
        let a = a + 1;
        println!("{}", a); // 출력: 3
    }

    println!("{}", a); // 출력: 2
}

세번째 let a = a + 1 문장은 내부 Scope에서 a(=2) + 1 = 3 을 갖는 변수 a를 만들게 되고, 이를 출력하면 3을 표시하게 된다. 하지만, 내부 Scope를 벗어나게 되면, 그 Scope 안의 변수 a는 소멸하게 되고, 외부 Scope의 변수 a, 즉 2를 갖게 된다.

참고로, 위 예제를 Shadowing이 아닌 mut를 써서 변경하면, 아래와 같은 코드가 될텐데, 이때의 출력은 3, 3 으로 다른 값을 출력함으로 알 수 있다.

fn main() {
    let mut a = 1;
    a = 2;
    {
        a = a + 1;
        println!("{}", a); // 출력: 3
    }

    println!("{}", a); // 출력: 3
}

This site is not affiliated with or endorsed by the Rust Foundation or Rust Project.