来看一个官方的例子:

1
2
3
4
5
6
7
8
fn main() {
let mut num = 5; // 定义一个可变的变量
let r1 = &num as *const i32; // 定义一个指向 num 的常量指针
let r2 = &mut num as *mut i32; // 定义一个指向 num 的可变指针

println!("r1 is: {}", *r1); // 打印 r1指向的值
println!("r2 is: {}", *r2); // 打印 r2指向的值
}

该代码不能通过编译,因为我们在安全的代码中进行了裸指针的解引用。如果没有下面的两行 println打印则可以编译通过,如果要解引用裸指针,则需要定义一个 unsafe 块,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn main() {
let mut num = 5; // 定义一个可变的变量
let r1 = &num as *const i32; // 定义一个指向 num 的常量指针
let r2 = &mut num as *mut i32; // 定义一个指向 num 的可变指针

unsafe {
println!("r1 is: {}", *r1); // 打印 r1指向的值
println!("r2 is: {}", *r2); // 打印 r2指向的值
*r2 = 10; // 修改 r2 指向的值
println!("r1 is: {}", *r1); // 打印 r1指向的值
println!("r2 is: {}", *r2); // 打印 r2指向的值
}
println!("num is: {}", num); // 打印 num 的值
}

通过这段代码可以看到在不安全的代码块中可以接引用裸指针,r1r2 都指向了同一个变量 numr1是不能修改的,r2是可以修改的。就和C语言中的指针一样,可以定义多个执行同一个变量(地址)的指针。