Rust语言从入门到精通系列 - Borrow和BorrowMut特征

2254 字
11 分钟
Rust语言从入门到精通系列 - Borrow和BorrowMut特征

Rust 语言是一种系统级编程语言,它强调安全、速度和并发性。Rust 的内存管理机制是通过所有权系统实现的,这意味着每个值都有一个所有者,并且只能有一个所有者。当值超出其所有者的范围时,它将被释放。这种机制可以防止许多常见的内存错误,如空指针引用和野指针。

然而,有时候我们需要在不拥有值的情况下对其进行操作。Rust 提供了 borrow 和 borrow_mut 两个方法来实现这个目的。这两个方法允许我们借用值的所有权,而不是拥有它。这种方式可以使我们在不破坏所有权系统的前提下,进行一些特定的操作。

基础用法#

Borrow#

Borrow 方法用于借用一个值的不可变引用。这个方法的语法如下:

fn borrow(&self) -> &T

其中,&self表示当前值的引用,&T表示返回的借用值的类型。下面是一个使用 borrow 方法的示例:

fn main() {
let v = vec![1, 2, 3];
let r = v.borrow();
println!("{:?}", r);
}

这个示例中,我们创建了一个包含三个元素的向量。然后,我们使用 borrow 方法来借用这个向量的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为[1, 2, 3]

BorrowMut#

BorrowMut 方法用于借用一个值的可变引用。这个方法的语法如下:

fn borrow_mut(&mut self) -> &mut T

其中,&mut self表示当前值的可变引用,&mut T表示返回的借用值的类型。下面是一个使用 borrow_mut 方法的示例:

fn main() {
let mut v = vec![1, 2, 3];
v.push(4);
println!("{:?}", v);
}

这个示例中,我们创建了一个包含三个元素的向量,并将其绑定到变量 v 上。然后,我们使用 borrow_mut 方法来借用这个向量的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push 方法向向量中添加一个元素。最后,我们打印出 v 的值。输出结果为[1, 2, 3, 4]

借用一个字符串的不可变引用#

fn main() {
let s = String::from("hello");
let r = s.borrow();
println!("{}", r);
}

这个示例中,我们创建了一个包含字符串”hello”的字符串。然后,我们使用 borrow 方法来借用这个字符串的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为hello

借用一个字符串的可变引用#

fn main() {
let mut s = String::from("hello");
s.push_str(", world!");
println!("{}", s);
}

这个示例中,我们创建了一个包含字符串”hello”的字符串,并将其绑定到变量 s 上。然后,我们使用 borrow_mut 方法来借用这个字符串的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push_str 方法向字符串中添加一个后缀。最后,我们打印出 s 的值。输出结果为hello, world!

借用一个数组的不可变引用#

fn main() {
let a = [1, 2, 3];
let r = a.borrow();
println!("{:?}", r);
}

这个示例中,我们创建了一个包含三个元素的数组。然后,我们使用 borrow 方法来借用这个数组的不可变引用,并将其绑定到变量 r 上。最后,我们打印出 r 的值。输出结果为[1, 2, 3]

借用一个数组的可变引用#

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]

借用一个结构体的不可变引用#

#[derive(Debug)]
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 }

借用一个结构体的可变引用#

#[derive(Debug)]
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 }

进阶用法#

借用一个值的引用#

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]

借用一个值的可变引用的引用#

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]

借用一个值的不可变引用的可变引用#

fn main() {
let mut 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]

借用一个值的可变引用的不可变引用#

fn main() {
let mut v1 = vec![1, 2, 3];
let v2 = vec![4, 5, 6];
v1.push(4);
println!("{:?}", v1);
}

这个示例中,我们创建了两个包含三个元素的向量 v1 和 v2,并将 v1 绑定到变量 v1 上。然后,我们使用 borrow_mut 方法来借用 v1 的可变引用,并将其绑定到变量 r 上。接着,我们使用 r 的 push 方法向 v1 中添加一个元素。最后,我们打印出 v1 的值。输出结果为[1, 2, 3, 4]

最佳实践#

在使用 borrow 和 borrow_mut 方法时,需要注意以下几点:

  1. 不要同时借用一个值的可变引用和不可变引用。这会导致编译器错误。

  2. 不要在可变引用的生命周期内使用不可变引用。这会导致编译器错误。

  3. 不要在不可变引用的生命周期内使用可变引用。这会导致编译器错误。

  4. 在使用 borrow 和 borrow_mut 方法时,应该尽量减少借用的范围和时间。这可以提高代码的可读性和可维护性。

下面是一个示例代码,展示了如何使用 borrow 和 borrow_mut 方法来操作一个向量:

fn main() {
let mut v = vec![1, 2, 3];
{
v.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 方法时,需要注意借用的范围和时间,以及避免出现编译器错误。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
Rust语言从入门到精通系列 - Borrow和BorrowMut特征
https://tinyzzh.github.io/posts/2023-04-03-rust_lang_tutorial_130_trait_borrow_borrowmut/
作者
TinyZ Zzh
发布于
2023-04-03
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
TinyZ Zzh
专注于高并发服务器、网络游戏相关(Java、PHP、Unity3D、Unreal Engine等)技术,热爱游戏事业, 正在努力实现自我价值当中。
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
211
分类
38
标签
200
总字数
337,853
运行时长
0
最后活动
0 天前

文章目录