fn func(s: *mut String, a: *mut i32) -> usize {
println!("{}", unsafe { *s });
println!("{}", unsafe { *a });
unsafe { (*s).len() }
}
fn main() {
let mut s = String::from("hello");
let mut a = 10;
func(&mut s, &mut a);
}
上述代码失败并显示错误:
error[E0507]: cannot move out of dereference of raw pointer
--> src/main.rs:2:29
|
2 | println!("{}", unsafe { *s });
| ^^ cannot move out of dereference of raw pointer
为什么String
而不是i32
?为什么抱怨“移动”?
答案 0 :(得分:4)
为什么
String
而不是i32
呢?
Rust实现how to convert a bit mask prefix into a dotted-decimal notation中的基本整数类型(实际上是许多其他类型)。他们有“复制语义”,而不是“移动语义”。这里所有权没有变化......你正在复制价值。 String
未实现 Copy
特征,因此此绑定具有“移动语义”。
这不是原始指针所特有的,也不与它们的可变性有任何关系。 the Copy
trait使用不可变引用会发生这种情况:
fn func(s: &String, a: &i32) {
let _x = *s;
let _x = *a;
}
为什么抱怨“移动”?
这样做是因为您试图将所有权移出unsafe
块。只要您对此无关紧要,那么您需要在unsafe
块中包含“移动”,这样编译器就可以让您自己动手。因此,如果您重构代码以便不移动到unsafe
块的之外,代码将编译:
unsafe {
println!("{}", *s);
}
要重新讨论Shepmaster在你的问题评论中的观点...如果术语“移动”听起来很陌生,那么你不应该首先使用原始指针/ unsafe
块,并且应该而是回到Rust的可用文档来理解这个概念......因为它是核心概念。