Enhance code examples

pull/1555/head
josephzxy 4 months ago
parent e60a32f838
commit 745e6e0551

@ -37,6 +37,17 @@ struct Node<T> {
}
```
细心的同学可能会发现,此时 `Link<T>``tail` 的类型 `*mut Node<T>` 一致了。我们可以把 `tail` 的类型也改为 `Link<T>` ,让代码更一致。
```rust
pub struct List<T> {
head: LinkT>,
// tail: *mut Node<T>,
tail: Link<T>, // 新老好人卡此时一致了
}
```
请大家牢记:当使用裸指针时,`Option` 对我们是相当不友好的,所以这里不再使用。在后面还将引入 `NonNull` 类型,但是现在还无需操心。
## 基本操作
@ -89,31 +100,31 @@ struct Node<T> {
> 将裸指针转换成 `Box` 以实现自动的清理:
>
> ```rust
>
> let x = Box::new(String::from("Hello"));
> let ptr = Box::into_raw(x);
> let x = unsafe { Box::from_raw(ptr) };
太棒了,简直为我们量身定制。而且它还很符合我们试图遵循的规则: 从安全的东东开始,将其转换成裸指针,最后再将裸指针转回安全的东东以实现安全的 drop。
现在,我们就可以到处使用裸指针,也无需再注意 unsafe 的范围,反正现在都是 unsafe 了,无所谓。
现在,我们就可以到处使用裸指针,只不过要注意 unsafe 的范围要尽可能小。大家可以再看下[之前的章节](https://course.rs/advance/unsafe/intro.html#控制-unsafe-的使用边界) 巩固巩固。
```rust
pub fn push(&mut self, elem: T) {
unsafe {
// 一开始就将 Box 转换成裸指针
let new_tail = Box::into_raw(Box::new(Node {
elem: elem,
next: ptr::null_mut(),
}));
if !self.tail.is_null() {
// 一开始就将 Box 转换成裸指针
let new_tail = Box::into_raw(Box::new(Node {
elem: elem,
next: ptr::null_mut(),
}));
if !self.tail.is_null() {
unsafe {
(*self.tail).next = new_tail;
} else {
self.head = new_tail;
}
self.tail = new_tail;
} else {
self.head = new_tail;
}
self.tail = new_tail;
}
```
@ -126,7 +137,10 @@ pub fn pop(&mut self) -> Option<T> {
if self.head.is_null() {
None
} else {
let head = Box::from_raw(self.head);
let head;
unsafe {
head = Box::from_raw(self.head);
}
self.head = head.next;
if self.head.is_null() {

Loading…
Cancel
Save