Rust语言从入门到精通系列 - Borrow和BorrowMut特征
Rust 语言是一种系统级编程语言,它强调安全、速度和并发性。Rust 的内存管理机制是通过所有权系统实现的,这意味着每个值都有一个所有者,并且只能有一个所有者。当值超出其所有者的范围时,它将被释放。这种机制可以防止许多常见的内存错误,如空指针引用和野指针。
然而,有时候我们需要在不拥有值的情况下对其进行操作。Rust 提供了 borrow 和 borrow_mut 两个方法来实现这个目的。这两个方法允许我们借用值的所有权,而不是拥有它。这种方式可以使我们在不破坏所有权系统的前提下,进行一些特定的操作。
基础用法
Borrow
Borrow 方法用于借用一个值的不可变引用。这个方法的语法如下:
1
fn borrow(&self) -> &T
其中,&self
表示当前值的引用,&T
表示返回的借用值的类型。下面是一个使用 borrow 方法的示例:
1
2
3
4
5
fn main() {
let v = vec![1, 2, 3];
let r = v.borrow();
println!("{:?}", r);
}
这个示例中,我们创建了一个包含三个元素的向量。然后,我们使用 borrow 方法来借用这个向量的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为[1, 2, 3]
。
BorrowMut
BorrowMut 方法用于借用一个值的可变引用。这个方法的语法如下:
1
fn borrow_mut(&mut self) -> &mut T
其中,&mut self
表示当前值的可变引用,&mut T
表示返回的借用值的类型。下面是一个使用 borrow_mut 方法的示例:
1
2
3
4
5
6
fn main() {
let mut v = vec![1, 2, 3];
let r = v.borrow_mut();
r.push(4);
println!("{:?}", v);
}
这个示例中,我们创建了一个包含三个元素的向量,并将其绑定到变量 v 上。然后,我们使用 borrow_mut 方法来借用这个向量的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push 方法向向量中添加一个元素。最后,我们打印出 v 的值。输出结果为[1, 2, 3, 4]
。
借用一个字符串的不可变引用
1
2
3
4
5
fn main() {
let s = String::from("hello");
let r = s.borrow();
println!("{}", r);
}
这个示例中,我们创建了一个包含字符串”hello”的字符串。然后,我们使用 borrow 方法来借用这个字符串的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为hello
。
借用一个字符串的可变引用
1
2
3
4
5
6
fn main() {
let mut s = String::from("hello");
let r = s.borrow_mut();
r.push_str(", world!");
println!("{}", s);
}
这个示例中,我们创建了一个包含字符串”hello”的字符串,并将其绑定到变量 s 上。然后,我们使用 borrow_mut 方法来借用这个字符串的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push_str 方法向字符串中添加一个后缀。最后,我们打印出 s 的值。输出结果为hello, world!
。
借用一个数组的不可变引用
1
2
3
4
5
fn main() {
let a = [1, 2, 3];
let r = a.borrow();
println!("{:?}", r);
}
这个示例中,我们创建了一个包含三个元素的数组。然后,我们使用 borrow 方法来借用这个数组的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为[1, 2, 3]
。
借用一个数组的可变引用
1
2
3
4
5
6
fn main() {
let mut a = [1, 2, 3];
let r = a.borrow_mut();
r[1] = 4;
println!("{:?}", a);
}
这个示例中,我们创建了一个包含三个元素的数组,并将其绑定到变量 a 上。然后,我们使用 borrow_mut 方法来借用这个数组的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 来修改数组中的一个元素。最后,我们打印出 a 的值。输出结果为[1, 4, 3]
。
借用一个结构体的不可变引用
1
2
3
4
5
6
7
8
9
10
struct Point {
x: i32,
y: i32,
}
fn main() {
let p = Point { x: 1, y: 2 };
let r = &p;
println!("{:?}", r);
}
这个示例中,我们创建了一个包含 x 和 y 两个字段的结构体 Point,并将其绑定到变量 p 上。然后,我们使用&符号来借用这个结构体的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为Point { x: 1, y: 2 }
。
借用一个结构体的可变引用
1
2
3
4
5
6
7
8
9
10
11
struct Point {
x: i32,
y: i32,
}
fn main() {
let mut p = Point { x: 1, y: 2 };
let r = &mut p;
r.x = 3;
println!("{:?}", p);
}
这个示例中,我们创建了一个包含 x 和 y 两个字段的结构体 Point,并将其绑定到变量 p 上。然后,我们使用&mut 符号来借用这个结构体的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 来修改结构体中的一个字段。最后,我们打印出 p 的值。输出结果为Point { x: 3, y: 2 }
。
进阶用法
借用一个值的引用
1
2
3
4
5
6
fn main() {
let v1 = vec![1, 2, 3];
let v2 = vec![4, 5, 6];
let r = &v1;
println!("{:?}", r);
}
这个示例中,我们创建了两个包含三个元素的向量 v1 和 v2。然后,我们使用&符号来借用 v1 的引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为[1, 2, 3]
。
借用一个值的可变引用的引用
1
2
3
4
5
6
7
fn main() {
let mut v1 = vec![1, 2, 3];
let v2 = vec![4, 5, 6];
let r = &mut &mut v1;
(*r).push(4);
println!("{:?}", v1);
}
这个示例中,我们创建了两个包含三个元素的向量 v1 和 v2,并将 v1 绑定到变量 v1 上。然后,我们使用&mut 符号来借用 v1 的可变引用的可变引用,并将其绑定到变量 r 上。接着,我们使用*r 来访问 v1,并向其添加一个元素。最后,我们打印出 v1 的值。输出结果为[1, 2, 3, 4]
。
借用一个值的不可变引用的可变引用
1
2
3
4
5
6
7
fn main() {
let v1 = vec![1, 2, 3];
let v2 = vec![4, 5, 6];
let r = &mut &v1;
**r = vec![7, 8, 9];
println!("{:?}", v1);
}
这个示例中,我们创建了两个包含三个元素的向量 v1 和 v2。然后,我们使用&符号来借用 v1 的不可变引用的可变引用,并将其绑定到变量 r 上。接着,我们使用**r 来访问 v1,并将其替换为一个新的向量。最后,我们打印出 v1 的值。输出结果为[7, 8, 9]
。
借用一个值的可变引用的不可变引用
1
2
3
4
5
6
7
fn main() {
let mut v1 = vec![1, 2, 3];
let v2 = vec![4, 5, 6];
let r = &v1.borrow_mut();
r.push(4);
println!("{:?}", v1);
}
这个示例中,我们创建了两个包含三个元素的向量 v1 和 v2,并将 v1 绑定到变量 v1 上。然后,我们使用 borrow_mut 方法来借用 v1 的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push 方法向 v1 中添加一个元素。最后,我们打印出 v1 的值。输出结果为[1, 2, 3, 4]
。
最佳实践
在使用 borrow 和 borrow_mut 方法时,需要注意以下几点:
-
不要同时借用一个值的可变引用和不可变引用。这会导致编译器错误。
-
不要在可变引用的生命周期内使用不可变引用。这会导致编译器错误。
-
不要在不可变引用的生命周期内使用可变引用。这会导致编译器错误。
-
在使用 borrow 和 borrow_mut 方法时,应该尽量减少借用的范围和时间。这可以提高代码的可读性和可维护性。
下面是一个示例代码,展示了如何使用 borrow 和 borrow_mut 方法来操作一个向量:
1
2
3
4
5
6
7
8
9
10
11
fn main() {
let mut v = vec![1, 2, 3];
{
let r = v.borrow_mut();
r.push(4);
}
{
let r = v.borrow();
println!("{:?}", r);
}
}
这个示例中,我们创建了一个包含三个元素的向量,并将其绑定到变量 v 上。然后,我们使用 borrow_mut 方法来借用这个向量的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push 方法向向量中添加一个元素。然后,我们使用 borrow 方法来借用这个向量的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为[1, 2, 3, 4]
。
总结
borrow 和 borrow_mut 方法是 Rust 语言中非常重要的方法,它们允许我们在不拥有值的情况下对其进行操作。这种方式可以使我们在不破坏所有权系统的前提下,进行一些特定的操作。在使用 borrow 和 borrow_mut 方法时,需要注意借用的范围和时间,以及避免出现编译器错误。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 TinyZ Zzh (包含链接: https://tinyzzh.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。 如有任何疑问,请 与我联系 (tinyzzh815@gmail.com) 。
评论