rust

rust - 변수와 상수

쓰러진복돌이 2024. 3. 8. 12:19

1. 변수 선언

rust는 let을 변수로 사용한다.

let a = 1;
let b = 3.14;
 

2. 불변성

Rust 프로그래밍 언어에서 모든 변수는 "디폴트로" 불변성(Immutability)의 성질을 갖는다.

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

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

 

3. 가변설정 (mutable)

가변적 변수 mut 키워드를 지정해 가변의 데이터로 사용할 수 있다.

fn main() {
    let mut x = 42;
    println!("{}", x);
    x = 13;
    println!("{}", x);

    let y = 23;
    println!("{}", y);
    y = 9;  // 에러
    println!("{}", y);
}

 

4. 상수

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

fn main() {
    const PI: f64 = 3.141592;
 
    let area = PI * 5.0 * 5.0;
    println!("{}", area);
}

 

5. Type annotation

일반적으로 Rust 컴파일러가 데이터 타입 추론을 통해 변수 타입을 결정하지만, 종종 명확히 판단을 내리지 못해 프로그래머가 직접 타입 부연설명을 해주어야 한다.

 

6. Shadowing

Rust의 특별한 기능 중의 하나로 Shadowing 기능을 들 수 있다. Rust 코드에서 "let"은 변수를 선언하는데 사용되는데, 한 코드 Scope에서 동일한 변수명을 let으로 여러번 정의하는 것이 가능(nodejs는 불가)하다. 예를 들어, 아래 예제에서 변수 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
}