当前位置:网站首页>Rust 的 Box指针
Rust 的 Box指针
2022-04-23 05:45:00 【许野平】
Rust 的 Box指针
1 指向 Copy 类型的数据
像 i32 这样的简单类型,实现了 Copy 特性,通常数据保存在栈空间。看个简单例子,看看如何用 Box 指针封装这类数据:
fn main() {
let x: Box<i32> = Box::new(123);
let y: i32 = *x;
println!("{:?}, {:?}", x, y);
}
---------------------------------
>cargo run
123, 123
Box 的作用是把包装的数据变成指针。 Rust 中也有类似 C 语言的裸指针,很不安全。通常我们用 Box 实现指针的功能,可确保代码安全。
我们也可以修改 Box 指向的内容:
fn main() {
let mut x: Box<i32> = Box::new(123);
*x = 456;
println!("{:?}", x);
}
这与 C 语言里的指针几乎一样。
2 指向 Move 类型的数据
像 String 这样的数据类型,没有实现 Copy 特性,通常数据保存在堆空间。看个简单例子,看看如何用 Box 指针封装这类数据:
fn main() {
let x = String::from("Hello!");
let y = Box::new(x);
let z = *y;
println!("{:?}, {:?}, {:?}", x, y, z);
}
---------------------------------
>cargo run
let x = String::from("Hello!");
| - move occurs because `x` has type `String`, which does not implement the `Copy` trait
3 | let y = Box::new(x);
| - value moved here
4 | let z = *y;
5 | println!("{:?}, {:?}, {:?}", x, y, z);
| ^ value borrowed here after move
编译出现错误。原因是,x 没有实现 Copy 特性,let y = Box::new(x);
把 x 的值 move 入了 Box。因此,后面的 println
命令,不能再打印 x 的值了。
fn main() {
let x = String::from("Hello!");
let y = Box::new(x);
let z = *y;
println!("{:?}, {:?}", y, z);
}
---------------------------------
>cargo run
--> src\main.rs:5:28
|
3 | let y = Box::new(x);
| - move occurs because `y` has type `Box<String>`, which does not implement the `Copy` trait
4 | let z = y;
| - value moved here
5 | println!("{:?}, {:?}", y, z);
| ^ value borrowed here after move
去掉 x,仍然会出错误。原因是 let z = *y;
把 Box 包装的 String 值 move 到 z 了。换成 let z = y;
也是一样,这个参考一下 rust 的解引用机制。
继续修改一下:
fn main() {
let x = String::from("Hello!");
let y = Box::new(x);
println!("{:?}", y);
}
---------------------------------
>cargo run
"Hello!"
这次 Ok 了!
3 Box 的价值所在
看一个链表节点设计的例子:
struct Node {
data: i32,
next: Option<Node>,
}
fn main() {
let x = Node {
data: 123,
next: None,
};
let y = Box::new(x);
println!("{:?}", y);
}
---------------------------------
>cargo run
--> src\main.rs:1:1
|
1 | struct Node {
| ^^^^^^^^^^^ recursive type has infinite size
2 | data: i32,
3 | next: Option<Node>,
| ------------ recursive without indirection
编译器提示需要用间接的方法实现递归定义。因为直接用 Option<Node>
,由于 Node 中存在递归定义,其大小无法确定(实际上可能是无穷大)。所以,需要用指针来代替 Node。代码修改如下:
#[derive (Debug)]
struct Node {
data: i32,
next: Option<Box<Node>>,
}
fn main() {
let x = Node {
data: 123,
next: None,
};
let y = Box::new(x);
println!("{:?}", y);
}
---------------------------------
>cargo run
Node {
data: 123, next: None }
很好呀!
由于 Node 含有指针,因此也是不能 Copy 的数据类型,用 Box 封装时与 String 类型有类似的特点。
版权声明
本文为[许野平]所创,转载请带上原文链接,感谢
https://yeping.blog.csdn.net/article/details/123041445
边栏推荐
猜你喜欢
Understanding and installing MySQL
Motor and drive (Qi Jinqing Edition)
RPC must know and know
-- SQL query and return limit rows
IO multiplexing of 09 redis
A sharp tool to improve work efficiency
卡尔曼滤波与惯性组合导航
Addition, deletion, query and modification of data
[leetcode 202] happy number
Generate excel template (drop-down selection, multi-level linkage)
随机推荐
Stability building best practices
Understanding and use of tp50, tp90 and tp99
[leetcode 6] zigzag transformation
[leetcode 67] sum of two binary numbers
Problems and solutions of database migration
队列解决约瑟夫问题
Failure to deliver XID in Seata distributed transaction project
Sakura substring thinking
Best practices for MySQL storage time
Create binary tree
-- SQL query and return limit rows
[leetcode 19] delete the penultimate node of the linked list
Custom exception class
SQL -- data definition
2. Devops sonar installation
Database - sorting data
Consistent hash algorithm used for redis cache load balancing
scikit-learn sklearn 0.18 官方文档中文版
8. Integer Decomposition
線性代數第二章-矩陣及其運算