取消引用指向 String 的原始指针和指向 i32 的原始指针之间有什么区别?
What is the difference between dereferencing a raw pointer to a String and a raw pointer to an i32?
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
?为什么它抱怨 "move"?
Why does it happen for String
and not for i32
?
Rust 中的基本整数类型(实际上还有许多其他类型)实现 the Copy
trait。他们有 "copy semantics",而不是 "move semantics"。这里没有所有权的变化......你正在复制价值。 String
未实现 Copy
特征,因此此绑定具有 "move semantics"。
这不是原始指针独有的,也与它们的可变性无关。 This example shows 这可能发生在不可变引用中:
fn func(s: &String, a: &i32) {
let _x = *s;
let _x = *a;
}
Why is it complaining of a "move"?
它这样做是因为您正试图将所有权移出 unsafe
块。只要您对此无所谓,就需要将 "move" 包含在 unsafe
块中,这样编译器就会让您搬起石头砸自己的脚。因此,如果您重组代码以便 不移到 unsafe
块的 之外,代码将编译:
unsafe {
println!("{}", *s);
}
Here it is running in the playground.
虽然要重申 Shepmaster 在对您的问题的评论中的观点...如果术语 "move" 对您来说听起来很陌生,那么您不应该在中使用原始指针/unsafe
块第一名,应该返回 Rust 的可用文档来理解这个概念。因为它是一个核心概念。
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
?为什么它抱怨 "move"?
Why does it happen for
String
and not fori32
?
Rust 中的基本整数类型(实际上还有许多其他类型)实现 the Copy
trait。他们有 "copy semantics",而不是 "move semantics"。这里没有所有权的变化......你正在复制价值。 String
未实现 Copy
特征,因此此绑定具有 "move semantics"。
这不是原始指针独有的,也与它们的可变性无关。 This example shows 这可能发生在不可变引用中:
fn func(s: &String, a: &i32) {
let _x = *s;
let _x = *a;
}
Why is it complaining of a "move"?
它这样做是因为您正试图将所有权移出 unsafe
块。只要您对此无所谓,就需要将 "move" 包含在 unsafe
块中,这样编译器就会让您搬起石头砸自己的脚。因此,如果您重组代码以便 不移到 unsafe
块的 之外,代码将编译:
unsafe {
println!("{}", *s);
}
Here it is running in the playground.
虽然要重申 Shepmaster 在对您的问题的评论中的观点...如果术语 "move" 对您来说听起来很陌生,那么您不应该在中使用原始指针/unsafe
块第一名,应该返回 Rust 的可用文档来理解这个概念。因为它是一个核心概念。