수색…
소개
통사론
- let x : & T = ... // x는 불변의 참조이다.
- x : & mut T = ... // x는 독점적이고 변경 가능한 참조입니다.
- let = = & mut foo; // foo를 변경 가능하게 빌려줍니다 (즉, 독점적으로).
- let = = & foo; // foo를 빌려줍니다.
- 하자 _ = foo; // foo 이동 (소유권 필요)
비고
- 이전 버전의 Rust (1.0 이전, 2015 년 5 월)에서 소유 변수의 유형은
~
시작했습니다. 아주 오래된 예에서 이것을 볼 수 있습니다.
소유권 및 차용
Rust의 모든 값에는 정확히 한 명의 소유자가 있습니다. 소유자는 범위를 벗어날 때 해당 값을 삭제해야하며 해당 값의 소유권을 옮길 수있는 유일한 사람입니다. 값의 소유자는 다른 코드가 그 값을 빌리 도록하여 참조 를 제공 할 수 있습니다. 언제든지 값에 대한 불변의 참조가있을 수 있습니다.
let owned = String::from("hello");
// since we own the value, we may let other variables borrow it
let immutable_borrow1 = &owned;
// as all current borrows are immutable, we can allow many of them
let immutable_borrow2 = &owned;
// in fact, if we have an immutable reference, we are also free to
// duplicate that reference, since we maintain the invariant that
// there are only immutable references
let immutable_borrow3 = &*immutable_borrow2;
또는 하나의 변경 가능한 참조 ( ERROR
는 컴파일 타임 오류를 나타냄) :
// for us to borrow a value mutably, it must be mutable
let mut owned = String::from("hello");
// we can borrow owned mutably
let mutable_borrow = &mut owned;
// but note that we cannot borrow owned *again*
let mutable_borrow2 = &mut owned; // ERROR, already borrowed
// nor can we cannot borrow owned immutably
// since a mutable borrow is exclusive.
let immutable_borrow = &owned; // ERROR, already borrowed
값에 미해결 참조 (변경 가능 또는 불변)가있는 경우 해당 값을 이동할 수 없습니다 (즉, 소유권이 떨어져 있음). 우리는 모든 참조가 먼저 값을 이동하도록 허용되었는지 확인해야합니다.
let foo = owned; // ERROR, outstanding references to owned
let owned = String::from("hello");
{
let borrow = &owned;
// ...
} // the scope ends the borrow
let foo = owned; // OK, owned and not borrowed
차용 및 수명
녹의 모든 값은 수명이 있습니다. 값의 수명은 코드 세그먼트에서 값이 이동 된 위치 또는 포함 된 범위의 끝 부분에 적용됩니다.
{
let x = String::from("hello"); // +
// ... :
let y = String::from("hello"); // + |
// ... : :
foo(x) // x is moved | = x's lifetime
// ... :
} // = y's lifetime
값을 빌릴 때마다 결과 참조의 수명 이 빌린 값의 수명에 연결됩니다.
{
let x = String::from("hello");
let y = String::from("world");
// when we borrow y here, the lifetime of the reference
// stored in foo is equal to the lifetime of y
// (i.e., between let y = above, to the end of the scope below)
let foo = &y;
// similarly, this reference to x is bound to the lifetime
// of x --- bar cannot, for example, spawn a thread that uses
// the reference beyond where x is moved below.
bar(&x);
}
소유권 및 함수 호출
함수를 작성할 때 소유권과 관련된 대부분의 질문이 생깁니다. 함수의 인수 유형을 지정할 때 그 값이 전달되는 방법 을 선택할 수 있습니다. 읽기 전용 액세스 만 필요하면 불변 참조를 취할 수 있습니다.
fn foo(x: &String) {
// foo is only authorized to read x's contents, and to create
// additional immutable references to it if it so desires.
let y = *x; // ERROR, cannot move when not owned
x.push_str("foo"); // ERROR, cannot mutate with immutable reference
println!("{}", x.len()); // reading OK
foo(x); // forwarding reference OK
}
foo
가 인수를 수정해야하는 경우에는 배타적 인 변경 가능 참조가 필요합니다.
fn foo(x: &mut String) {
// foo is still not responsible for dropping x before returning,
// nor is it allowed to. however, foo may modify the String.
let x2 = *x; // ERROR, cannot move when not owned
x.push_str("foo"); // mutating OK
drop(*x); // ERROR, cannot drop value when not owned
println!("{}", x.len()); // reading OK
}
&
및 &mut
중 하나를 지정하지 않으면 함수가 인수의 소유권을 갖게됩니다. 이것은 foo
가 이제 x
를 삭제할 책임이 있다는 것을 의미합니다.
fn foo(x: String) {
// foo may do whatever it wishes with x, since no-one else has
// access to it. once the function terminates, x will be dropped,
// unless it is moved away when calling another function.
let mut x2 = x; // moving OK
x2.push_str("foo"); // mutating OK
let _ = &mut x2; // mutable borrow OK
let _ = &x2; // immutable borrow OK (note that &mut above is dropped)
println!("{}", x2.len()); // reading OK
drop(x2); // dropping OK
}
소유권 및 복사 특성
일부 녹 유형은 Copy
특성을 구현합니다. 문제가되는 값을 소유하지 않고 Copy
유형을 이동할 수 있습니다. 이는 값의 내용을 새로운 동일한 값을 생성하기 위해 메모리에 바이트 단위로 간단히 복사 할 수 있기 때문입니다. 녹 (대부분 원시 bool
, usize
, f64
등)입니다 Copy
.
let x: isize = 42;
let xr = &x;
let y = *xr; // OK, because isize is Copy
// both x and y are owned here
특히 Vec
와 String
은 Copy
가 아닙니다 :
let x = Vec::new();
let xr = &x;
let y = *xr; // ERROR, cannot move out of borrowed content