벡터(vector) 타입

벡터(vector) 타입

Rust에서 배열(array)은 동일한 타입의 요소를 갖는 고정된 길이의 배열(fixed array)이다. 배열과 같이 동일한 타입의 요소들을 갖지만, 그 길이를 신축적으로 늘릴 수 있는 것을 벡터(vector)라고 한다.

벡터 생성 및 초기화

벡터를 생성하기 위해서는 Vec 타입의 생성자 함수인 new()를 호출한다. 즉, Vec::new() 를 호출하여 빈 벡터를 생성한다. 벡터는 항상 동일한 타입이어야 하는데, Vec::new() 함수를 호출하는 것으로는 어떤 타입의 데이타가 저장되는지 알 수 없으며 또한 아래 예제의 경우 다른 추가적인 코드에서 벡터 타입을 따로 추론할 수도 없으므로, 아래 예제의 v1 변수에는 변수 타입(type annotation)을 지정해 주어야 한다.

fn main() {
    // create empty i32 vector
    let v1: Vec<i32> = Vec::new();

    // create i32 vector with initial values
    let v2 = vec![1,2,3,4,5];

    println!("{:?} {:?}", v1, v2);
}

벡터를 생성할 때 만약 초기값을 함께 지정하고 싶으면, vec! 매크로를 사용할 수 있다. vec! 매크로는 초기값들을 가진 벡터를 생성하며, 여기에 새로운 요소를 추가하거나 수정할 수 있다. Vec::new()와 달리, vec! 매크로는 초기값들의 타입을 알 수 있으므로, 벡터의 변수 타입을 꼭 지정할 필요는 없다. 예를 들어, 위 예제에서 변수 v2는 vec! 매크로에 의해 1 ~ 5의 숫자를 가지므로, v2는 (정수의 디폴트 타입인) i32의 벡터 타입이 된다.

벡터 데이타 수정

벡터에 데이타를 추가하기 위해서는 push() 메서드를 사용한다. 벡터의 모든 요소를 출력하기 위해서는 "{:?}" 혹은 "{:#?}" 을 사용할 수 있다. 아래 예제에서 변수 v는 데이타가 수정되므로 mut 로 선언되었고, push() 메서드의 파라미터가 정수이므로 변수 v의 타입은 Vec<i32> 으로 자동 추론된다.

fn main() {
    let mut v = Vec::new();

    v.push(1);
    v.push(2);

    println!("{:?}", v);
}

벡터 데이타 읽기

벡터의 데이타를 읽는 방법으로는 (1) 벡터의 인덱스를 사용하거나 (2) 벡터의 get() 메서드를 사용하는 방법이 있다.

벡터의 인덱스를 사용하기 위해서는 벡터 변수에 레퍼런스를 취한 후 [ ] 안에 인덱스를 지정하면 된다. 예를 들어, 아래 예제에서 벡터 v의 두번째 요소를 읽기 위해서 &v[1] 과 같이 사용하였는데, 이는 벡터 v의 요소에 대해 Immutable Borrow를 한 것이다.

fn main() {
    let mut v = Vec::new();
    v.push(1);
    v.push(2);
    v.push(3);
    println!("v: {:?}", v);

    // (1) 인덱스 사용하여 읽기
    let n1 = &v[1];
    println!("&v[1]: {}", n1);

    // (2) get() 메서드로 읽기 
    let elem1 = v.get(1);
    println!("v.get(1): {:?}", elem1)
}

두번째 읽기 방법으로 벡터의 get() 메서드를 사용할 수 있는데, 위의 예제에서 벡터 v의 두번째 요소를 가져오기 위해 v.get(1)을 사용하였다. 이때의 리턴 타입은 Option<T> 으로 값이 없는 경우와 값이 있는 경우를 함께 리턴하게 된다. 예를 들어, v.get(10) 을 하게 되면 값이 없으므로 None이 리턴될 것이고, v.get(1)을 하면 값이 있는 경우로서 Some(2) 가 리턴될 것이다. 아래는 위 예제의 실행 결과를 표시한 것이다.

v: [1, 2, 3]
&v[1]: 2
v.get(1): Some(2)

벡터 인덱스를 사용할 때 만약 벡터 길이의 밖의 인덱스를 주게 되면 프로그램이 Crash 될 것이다. 반면, get() 메서드의 경우 None을 리턴하여 값이 없는 경우에 어떻게 처리할 지를 지정할 수 있다.

벡터 Iterator

벡터의 요소를 모두 하나씩 가져와 읽거나 수정하기 위해서, for 루프와 결합하여 Iteration 을 사용할 수 있다. 예를 들어, 아래는 벡터 v의 요소들을 하나씩 읽어 출력하는 예제이다.

fn main() {
    let v = vec![1,2,3];

    for n in &v {
        println!("{}", n);
    }
}

벡터의 요소를 수정하기 위해서는 먼저 벡터 변수 v를 mut 로 선언하고, "&mut v" 와 같이 mutable reference를 만들어 for 루프 안에서 각 요소를 수정한다. 아래 예제는 벡터 v의 각 요소에 1을 더하여 값을 출력하는 예이다. 레퍼런스 n에 대해 Dereference 연산자인 *을 사용하여 n이 가리키는 장소의 값을 가져오고, 그 장소에 1이 추가된 값을 저장하게 한다.

fn main() {
    let mut v = vec![1,2,3];

    for n in &mut v {
        *n = *n + 1;
        println!("{}", n);
    }
}

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