PDF版 ePub版

# 引用与借用

• 所有权，即正在读的这篇文章。

• 借用，和与它们相关的功能‘引用’

• 生存期，借用的先进理念

## 元

Rust 注重安全和速度。它通过许多‘零成本抽象’来完成这些目标，这意味着在 Rust 中，用尽可能少的抽象成本来保证它们正常工作。所有权制度是一个零成本抽象概念的一个主要例子。我们将在这篇指南中提到的所有分析都是在编译时完成的。你不用为了任何功能花费任何运行成本。

## 借用

fn foo(v1: Vec<i32>, v2: Vec<i32>) -> (Vec<i32>, Vec<i32>, i32) {
// do stuff with v1 and v2

// hand back ownership, and the result of our function
(v1, v2, 42)
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let (v1, v2, answer) = foo(v1, v2);

fn foo(v1: &Vec<i32>, v2: &Vec<i32>) -> i32 {
// do stuff with v1 and v2

// return the answer
42
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let answer = foo(&v1, &v2);

// we can use v1 and v2 here!

fn foo(v: &Vec<i32>) {
v.push(5);
}

let v = vec![];

foo(&v);

error: cannot borrow immutable borrowed content *v as mutable
v.push(5);
^

## &mut引用

let mut x = 5;
{
let y = &mut x;
*y += 1;
}
println!("{}", x);

error: cannot borrow x as immutable because it is also borrowed as mutable
println!("{}", x);
^
note: previous borrow of x occurs here; the mutable borrow prevents
subsequent moves, borrows, or modification of x until the borrow ends
let y = &mut x;
^
note: previous borrow ends here
fn main() {

}
^

## 规则

• 一个资源的从 0 到 N 的引用 ( &T ）。

• 一个可变的引用 ( &mut T

There is a ‘data race’ when two or more pointers access the same memory location at the same time, where at least one of them is writing, and the operations are not synchronized.

### 在作用域中的思考

let mut x = 5;
let y = &mut x;

*y += 1;

println!("{}", x);

error: cannot borrow x as immutable because it is also borrowed as mutable
println!("{}", x);
^

note: previous borrow ends here
fn main() {

}
^

let mut x = 5;

let y = &mut x;// -+ &mut borrow of x starts here
//  |
*y += 1;   //  |
//  |
println!("{}", x); // -+ - try to borrow x here
// -+ &mut borrow of x ends here

let mut x = 5;

{
let y = &mut x; // -+ &mut borrow starts here
*y += 1;//  |
}   // -+ ... and ends here

println!("{}", x);  // <- try to borrow x here

### 迭代器失效

let mut v = vec![1, 2, 3];

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

let mut v = vec![1, 2, 3];

for i in &v {
println!("{}", i);
v.push(34);
}

error: cannot borrow v as mutable because it is also borrowed as immutable
v.push(34);
^
note: previous borrow of v occurs here; the immutable borrow prevents
subsequent moves or mutable borrows of v until the borrow ends
for i in &v {
^
note: previous borrow ends here
for i in &v {
println!(“{}”, i);
v.push(34);
}
^

### 释放内存后再使用

let y: &i32;
{
let x = 5;
y = &x;
}

println!("{}", y);

error: x does not live long enough
y = &x;
^
note: reference must be valid for the block suffix following statement 0 at
2:16...
let y: &i32;
{
let x = 5;
y = &x;
}

note: ...but borrowed value is only valid for the block suffix following
statement 0 at 4:18
let x = 5;
y = &x;
}

let y: &i32;
let x = 5;
y = &x;

println!("{}", y);

error: x does not live long enough
y = &x;
^
note: reference must be valid for the block suffix following statement 0 at
2:16...
let y: &i32;
let x = 5;
y = &x;

println!("{}", y);
}

note: ...but borrowed value is only valid for the block suffix following
statement 1 at 3:14
let x = 5;
y = &x;

println!("{}", y);
}