What is the difference between dereferencing a raw pointer to a String and a raw pointer to an i32?

你离开我真会死。 提交于 2019-12-13 03:49:45

问题


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);
}

The above code fails with the error:

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

Why does it happen for String and not for i32? Why is it complaining of a "move"?


回答1:


Why does it happen for String and not for i32?

The basic integral types (and in fact, many other types) in Rust implement the Copy trait. They have "copy semantics", not "move semantics". There is no change of ownership here... you're copying out the value. String does not implement the Copy trait and therefore this binding has "move semantics".

This is not unique to raw pointers nor does it have anything to do with their mutability. This example shows this can happen with immutable references:

fn func(s: &String, a: &i32) {
    let _x = *s;
    let _x = *a;
}

Why is it complaining of a "move"?

It does this because you're attempting to move ownership out of the unsafe block. As long as you're care-free about this then you need to contain the "move" within the unsafe block so the compiler just lets you shoot yourself in the foot. As such, if you restructure your code so as to not move outside of the unsafe block, the code will compile:

unsafe {
    println!("{}", *s);
}

Here it is running in the playground.

To re-iterate Shepmaster's point in the comment on your question though... if the term "move" sounds foreign to you then you should not be using raw pointers/unsafe blocks in the first place and should instead head back to the available documentation for Rust to understand the concept.. as it is a core one.



来源:https://stackoverflow.com/questions/47879856/what-is-the-difference-between-dereferencing-a-raw-pointer-to-a-string-and-a-raw

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!