&mut unsafe { } 和 unsafe { &mut } 有什么区别?

tok*_*a-n 9 rust

我想将*mut指针转换为&mut引用。

// Both setting a value to ptr and getting a value from ptr succeeds.
let ptr: &mut usize = unsafe { &mut *(VIRTUAL_ADDRESS_TO_ACCESS_FREE_PAGE as *mut usize) };
Run Code Online (Sandbox Code Playgroud)

这有效。但是,如果&mutunsafe块之外,代码将无法部分工作。*ptr = foo不会存储foo到内存ptr点,但let foo = *ptr会将值分配*ptrfoo

// Setting a value to ptr fails, but getting a value from ptr succeeds.
let ptr: &mut usize = &mut unsafe { *(VIRTUAL_ADDRESS_TO_ACCESS_FREE_PAGE as *mut usize) };
Run Code Online (Sandbox Code Playgroud)

什么之间的区别unsafe { &mut }&mut unsafe{ }

Mas*_*inn 11

它与unsafe本身无关,而与块边界无关。

&*ptr是“重新借用”,它只是重新解释指向新表单的指针。因此,您将获得指向同一对象的不同类型的指针(一个原始指针和一个引用)。

&{*ptr}完全不同,因为{*ptr}强制复制[0](感谢 @harmic 提供):

块始终是值表达式并计算值表达式上下文中的最后一个表达式。如果确实需要,这可用于强制移动值。

然后它将借用该副本。这意味着您将获得两个指向完全不同对象的指针。

这些对象具有相同的值,因为一个人的指针是另一个的副本,因此读取似乎有效,但写入不起作用,因为......你不是在你认为你所在的地方写作。

请参阅此演示(不使用 mut 指针,因为无需演示该问题)


[0]更一般的移动,但在这里你指的usize是复制

  • 可能值得在[此处](https://doc.rust-lang.org/stable/reference/expressions/block-expr.html)添加一个链接,其中显示:“块始终是值表达式并评估最后一个表达式在值表达式上下文中。如果确实需要,这可以用于强制移动值。” (2认同)