Rust - Basic - 04 - 소유권

소유권

이해

Heap ,let b = a; , a invalid,( move) let b = a.clone(); , a String ( moved), reference (&String) moved ( reference borrowing) reference , &mut String , &mut reference (), & reference ()。 : reference’s scope , let &b = a let mut &c = a, borrow + reference reference valid, Dangling References

Rust trait annotation,

출처

https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html

… Rust에는 스택에 저장되는 정수 같은 형식에 붙일 수 있는 특별한 annotation인 Copy trait이 있습니다(trait에 대해서는 10장에서 더 설명합니다). 형식이 Copy trait을 구현하면 대입한 뒤에도 이전 변수를 계속 사용할 수 있습니다. 형식이나 그 일부가 Drop trait을 구현했다면 Rust는 해당 형식에 Copy trait을 annotation할 수 없게 합니다. 값이 범위를 벗어날 때 특별한 처리가 필요하면서 그 형식에 Copy annotation을 추가하면 컴파일 오류가 발생합니다. 형식에 Copy annotation을 추가해 trait을 구현하는 방법은 부록 C의 “파생 가능한 Trait” 을 참고하세요. 그렇다면 어떤 형식이 Copy trait을 구현할까요? 확실히 알려면 해당 형식의 문서를 확인해야 합니다. 일반적으로 단순한 스칼라 값의 묶음은 Copy를 구현할 수 있지만, 할당이 필요하거나 어떤 형태의 리소스인 것은 Copy를 구현할 수 없습니다. 다음은 Copy를 구현하는 형식입니다:

  • All the integer types, such as u32.
  • The Boolean type, bool, with values true and false.
  • All the floating point types, such as f64.
  • The character type, char.
  • Tuples, if they only contain types that also implement Copy. For example, (i32, i32) implements Copy, but (i32, String) does not. … 파일 이름: src/main.rs

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

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

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

오류는 다음과 같습니다.


$ cargo run
   Compiling ownership v0.1.0 (file:///projects/ownership)
error[E0499]: cannot borrow `s` as mutable more than once at a time
 --> src/main.rs:5:14
  |
4 |     let r1 = &mut s;
  |              ------ first mutable borrow occurs here
5 |     let r2 = &mut s;
  |              ^^^^^^ second mutable borrow occurs here
6 |
7 |     println!("{}, {}", r1, r2);
  |                        -- first borrow later used here

For more information about this error, try `rustc --explain E0499`.
error: could not compile `ownership` due to previous error

이 오류는 한 번에 borrow할 수 없어서 이 코드가 유효하지 않다는 뜻입니다. s as mutable more than once at a time. The first mutable borrow is in r1 and must last until it’s used in the println!, but between the creation of that mutable reference and its usage, we tried to create another mutable reference in r2 that borrows the same data as r1. … 중괄호로 새 scope를 만들면 여러 가변 reference를 사용할 수 있지만, 동시에 존재할 수는 없습니다:


    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;

가변 reference와 불변 reference를 함께 사용할 때도 비슷한 규칙이 적용됩니다. 다음 코드는 오류를 발생시킵니다:


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

    let r1 = &s; // no problem
    let r2 = &s; // no problem
    let r3 = &mut s; // BIG PROBLEM

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

오류는 다음과 같습니다.


$ cargo run
   Compiling ownership v0.1.0 (file:///projects/ownership)
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
 --> src/main.rs:6:14
  |
4 |     let r1 = &s; // no problem
  |              -- immutable borrow occurs here
5 |     let r2 = &s; // no problem
6 |     let r3 = &mut s; // BIG PROBLEM
  |              ^^^^^^ mutable borrow occurs here
7 |
8 |     println!("{}, {}, and {}", r1, r2, r3);
  |                                -- immutable borrow later used here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `ownership` due to previous error

불변 reference가 있는 동안에는 가변 reference를 함께 가질 수 없습니다. 불변 reference의 사용자는 자신이 읽는 값이 갑자기 바뀌리라고 예상하지 않습니다. 그러나 여러 불변 reference는 괜찮습니다. 데이터를 읽기만 하는 참조자는 다른 사람의 데이터 읽기에 영향을 줄 수 없기 때문입니다. reference의 scope는 reference가 도입된 지점부터 시작해 마지막으로 사용되는 시점까지 이어집니다. 예를 들어 다음 코드는 불변 reference의 마지막 사용인 println!이 가변 reference가 도입되기 전에 일어나므로 컴파일됩니다:


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

    let r1 = &s; // no problem
    let r2 = &s; // no problem
    println!("{} and {}", r1, r2);
    // variables r1 and r2 will not be used after this point

    let r3 = &mut s; // no problem
    println!("{}", r3);

…

Reference 규칙

reference에 대해 살펴본 내용을 정리하면 다음과 같습니다:

  • At any given time, you can have either one mutable reference or any number of immutable references.
  • reference는 항상 유효해야 합니다.