Rust 编程中的不安全操作
当我们想忽略Rust为我们提供的规范时,就会执行不安全操作。我们可以使用不同的不安全操作,主要是:
解引用原始指针
访问或修改静态可变变量
调用不安全的函数或方法
虽然Rust根本不建议我们应该使用不安全的操作,但我们应该只在想要绕过编译器提供的保护时才使用它们。
原始指针
在Rust中,原始指针*和引用&T执行几乎相同的事情,但引用总是安全的,因为由于借用检查器,编译器保证它们指向有效数据。
还应该注意的是,取消引用原始指针只能通过不安全的块来完成。
例子
考虑下面显示的示例:
fn main() { let raw_p: *const u32 = &10; println!("{}",*raw_p == 10); }
上面的代码会导致错误。
输出结果
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block --> src/main.rs:4:19 | 7 | println!("{}",*raw_p == 10); | ^^^^^^ dereference of raw pointer | = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
为了避免这个错误,我们需要使用一个不安全的块,然后我们可以解引用一个原始指针。
示例
考虑下面显示的代码:
fn main() { let raw_p: *const u32 = &10; unsafe { assert!(*raw_p == 10); } println!("工作正常!") }输出结果
工作正常!
不安全的功能
在Rust中调用不安全的函数会导致错误。
示例
考虑下面显示的代码:
use std::slice; fn main() { let some_vector = vec![1, 2, 3]; let pointer = some_vector.as_ptr(); let length = some_vector.len(); let my_slice: &[u32] = slice::from_raw_parts(pointer, length); assert_eq!(some_vector.as_slice(), my_slice); }输出结果
在上面的代码中,我们有一个不安全的slice::from_raw_parts函数,如果我们尝试运行这段代码,我们会看到这样的错误——
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block --> src/main.rs:10:28 | 10 | let my_slice: &[u32] = slice::from_raw_parts(pointer, length); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior
我们应该从unsafe块内部调用unsafe函数,而不是从任何地方调用该函数。
示例
考虑下面显示的代码:
use std::slice; fn main() { let some_vector = vec![1, 2, 3, 4]; let pointer = some_vector.as_ptr(); let length = some_vector.len(); unsafe { let my_slice: &[u32] = slice::from_raw_parts(pointer, length); assert_eq!(some_vector.as_slice(), my_slice); } println!("工作正常!!") }输出结果
工作正常!!