当前位置:网站首页>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
边栏推荐
- 5.The Simple Problem
- Example of reentrant lock thread waiting to wake up
- Kalman filter and inertial integrated navigation
- Supply chain service terms
- MySQL table constraints and table design
- Algèbre linéaire chapitre 1 - déterminants
- DBCP usage
- 程序設計訓練
- [leetcode 19] delete the penultimate node of the linked list
- Best practices for MySQL storage time
猜你喜欢
随机推荐
D. Optimal partition segment tree optimization DP
2. Average length of words
List segmentation best practices
Miscellaneous 1
Techniques et principes de détection
Cf6d lizards and fundamentals 2 problem solving
What is the difference between the basic feasible solution and the basic feasible solution in linear programming?
自动控制原理知识点整合归纳(韩敏版)
Customized communication between threads (reentrantlock)
[untitled] database - limit the number of returned rows
6.Reversal
进程间通信的方式
Collections multiple parameter sorting
Rust的闭包类型(Fn, FnMut, FnOne的区别)
MySQL occasional Caton
The bottom implementation principle of thread - static agent mode
Qthread simple test understanding
Why does the subscript of the array start from 0 instead of 1?
Explanation of login page
Explain of MySQL optimization








![[leetcode 401] binary Watch](/img/a5/538caf3a1a6143a47d79d947717554.png)
