시뻘건 개발 도전기

러스트 18 - Collections #1 : Vector 본문

프로그래밍/RUST

러스트 18 - Collections #1 : Vector

시뻘건볼때기 2019. 3. 31. 16:22
반응형

언제나 그렇듯 대부분의 언어는 컬렉션이라 불리는 데이터 구조를 제공한다.

우리가 공부했던 <변수와 타입 #2>튜플과 배열과는 다르게, 힙 영역에 저장된다.

즉, Compile Time에 데이터 크기를 알 필요가 없다는 뜻이 되며, 크기 확장 혹은 축소가 가능하다는 이야기다.

(우리가 공부할 각 컬렉션의 성격이 조금씩 다르니, 적절하게 사용할 수 있는 능력을 기르는 것이 옳다고 생각된다.)

 

이번 장에서 다룰 컬렉션은 Vector(벡터)다.

  • 메모리상에서 이웃되도록 모든 값을 넣는 단일 데이터 구조에 하나 이상의 값을 저장할 수 있도록 한다.
  • 같은 타입의 값만을 저장 가능하다.

 

벡터 정의 및 사용

fn main() {
    // vector 정의
    let mut vector: Vec<i32> = Vec::new();

    // vector에 값 삽입
    vector.push(1);
    vector.push(2);
    vector.push(3);

    // vector 출력
    println!("vector : {:?}", vector);

    // vector에서 값 제거
    vector.pop();
    println!("vector : {:?}", vector);

    vector.pop();
    println!("vector : {:?}", vector);

    vector.pop();
    println!("vector : {:?}", vector);
}

 

처음 언급한 바와 같이, i32타입을 저장할 것이라는 타입 명시만 있을 뿐, 크기는 지정하지 않았다.

사실 코드를 더 줄일 수 있다.

fn main() {
    // vector 정의
    let mut vector = vec![1, 2, 3];

    // vector 출력
    println!("vector : {:?}", vector);

    // vector에서 값 제거
    vector.pop();
    println!("vector : {:?}", vector);

    vector.pop();
    println!("vector : {:?}", vector);

    vector.pop();
    println!("vector : {:?}", vector);

}

 

러스트는 편리함을 제공해주기 위해 매크로를 제공한다. 같은 역할을 하는 코드지만, 상당히 축소된 것을 볼 수 있다.

 


 

이번엔 특정 값에 접근하는 방법 두 가지를 다뤄보자.

fn main() {
    // vector 정의
    let vector = vec![1, 2, 3];

    // vector 출력
    println!("vector : {:?}", vector);

    // vector 특정 값 접근 #1
    let var1: &i32 = &vector[2];
    // let var1: &i32 = &vector[100];               // Error 발생!!!
    println!("var1 : {}", var1);

    // vector 특정 값 접근 #2
    let var2: Option<&i32> = vector.get(2);
    // let var2: Option<&i32> = vector.get(100);    // None 반환
    println!("var2 : {:?}", var2);
}

[idx]를 이용한 방법(#1)Vec.get(int idx)를 이용한 방법(#2)이 있다.

 

#1의 경우 out of index가 발생할 경우 error를 떨구기 때문에, 좋지 않은 접근 방법이라고 볼 수 있다.

#2의 경우 None이 리턴되어 어떻게든 비벼볼 수 있는 상황이 된다.

즉, 항상, index로 무언가 접근할 경우 None을 적극적으로 활용하여 ERROR발생을 최소화 하자!!!

 


<러스트 13 - 구조체 #1>에서 다루었던 Borrowing에 대해 기억이 나지 않아서 다시 공부하고 왔다... 왜냐하면 지금 다시 나올 예정이니까...ㅎㅎㅎㅎㅎ

 

프로그램이 유효한 레퍼런스를 가지고 있을 경우 borrow checker는 이 레퍼런스와 벡터 내용에 대한 다른 레퍼런스가 유효하도록 소유권 및 빌림 규칙을 시행한다.

 

상위 코드의 #1방법으로 접근 한 뒤, vector를 사용해보자.

fn main() {
    // vector 정의
    let mut vector = vec![1, 2, 3];

    // vector 출력
    println!("vector : {:?}", vector);

    // vector 특정 값 접근 #1
    let var1: &i32 = &vector[2];
    // let var1: &i32 = &vector[100];               // Error 발생!!!
    println!("var1 : {}", var1);

    vector.push(99);

    // vector 특정 값 접근 #2
    // let var2: Option<&i32> = vector.get(2);
    // let var2: Option<&i32> = vector.get(100);    // None 반환
    // println!("var2 : {:?}", var2);
}

빌림을 다루는 장에서 이것저것 많은 것을 해보면 이 에러 메시지를 많이 보았을 것 같다.

이 메시지는 rust가 "야 너 이거 빌려줘놓고 왜 사용하려고 해? 안돼. 쓰지마."라고 이야기 해주는 것.

 


for문을 이용한 벡터의 모든 값 접근.

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

    // 벡터의 값 일정하게 변경
    for i in &mut vector {
        *i *= 3;
    }

    // 각 값 출력 #1
    println!("vector : {:?}", vector);

    // 각 값 출력 #2
    // for i in &vector {
    //     println!("vector : {}", i);
    // }
}

(개인적으로 출력에 대해서는 #1이 내 입맛에 맞다.

#2의 경우,  출력 만을 위해 for문이 들어가는 것이 맘에 들지 않는다. 만일, for문 안에서 값 변경이나 혹은 특정한 로직이 시행 된 후에 출력을 함께 하는 것이라면 #2가 맞지만, 출력만을 위해서 존재하는 것이라면 #1이 맞다고 본다.)

 


구조체와 같은 데이터 구조와 달리, 같은 타입의 데이터만을 저장할 수 있는 벡터는 불편하게 느낄 수 있을지 모르겠다.

우리는 어렵게 다루었던 열거형을 이용하여 이 제약을 풀 수 있을지 모른다!

    enum SpreadsheetCell {
        Int(i32),
        Float(f64),
        Text(String),
    }

    let row = vec![
        SpreadsheetCell::Int(3),
        SpreadsheetCell::Text(String::from("blue")),
        SpreadsheetCell::Float(10.12),
    ];

정수와 실수, 문자열을 담을 수 있게 되었다.

 

이와 같이 러스트가 Compile Time에 벡터 내에 저장되는 타입을 알아야할 필요가 있기 때문에 각 요소를 저장하기 위해 힙 메모리 영역이 얼마나 필요한지 알 수 있다.

(코드에서 이 벡터가 어떤 유형을 담는지 명시적으로 알 수 있다는 이점도 있다.)

 

 

반응형

'프로그래밍 > RUST' 카테고리의 다른 글

러스트 20 - 예외처리 #1 : panic!  (0) 2019.04.14
러스트 19 - Collections #2 : Hash Map  (0) 2019.03.31
러스트 17 - if let  (0) 2019.03.30
러스트 16 - 열거형 #2  (0) 2019.03.24
러스트 15 - 열거형 #1  (0) 2019.03.24
Comments