본문 바로가기

휴지통/러스트

러스트 Ownership2

    let mut s = String::from("hello");

    let r1 = &mut s;
    let r2 = &mut s;

    println!("{}, {}", r1, r2);

이 코드는 불가능 하다.

 

하나의 변수에 여러개의 mutable한 참조를 할 수 없다. Data race 개념인데 러스트는 data race 를 compile할때 막는다.

data race는 다음과 같은 상황에 발생한다.

- 두개 이상의 포인터가 한번에 같은시간에 가리킨다.

- 최소 하나의 포인터가 데이터를 쓰는데 사용되고있다.

- 데이터 접근하는데 동기화하는 매커니즘이 쓰이지 않는다.

 

let mut s = String::from("hello");

    {
        let r1 = &mut s;
    } // r1 goes out of scope here, so we can make a new reference with no problems.

    let r2 = &mut s;

scope 내부에서 사용하는것은 역시 가능하다.

 

fn main() {
    let mut s = String::from("hello world");

    let word = first_word(&s);

    s.clear(); // error!

    println!("the first word is: {}", word);
}

fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

해당 코드는 오류를 낸다.

 

clear 하는 순간 word를 출력할때 해당하는 값이 같이 사라지기 떄문이다. 따라서 이전까지 mut s 는 유지 되어야한다.

    let s = String::from("hello world");

    let hello = &s[0..5];
    let world = &s[6..11];

string slice 파이썬과 비슷해보인다.

 

let a = [1, 2, 3, 4, 5];

let slice = &a[1..3];

assert_eq!(slice, &[2, 3]);

배열역시 같은 방식으로 slicing 가능하다.