不可变变量, 为什么可以作为可变引用传入方法?
这里有人能帮我解释一下这个问题吗?谢谢了
let ptr = story.as_mut_ptr();as_mut_ptr的方法签名是:
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self as *mut str as *mut u8
}
story明明是个不可变变量, 为什么可以作为可变引用传入方法?
sorry, 我搞错了!少看了一句let mut story = mem::ManuallyDrop::new(story);
下面是完整代码
use std::mem;
fn main() {
let story = String::from("Rust By Practice");
// Prevent automatically dropping the String's data
let mut story = mem::ManuallyDrop::new(story);
let ptr = story.as_mut_ptr();
let len = story.len();
let capacity = story.capacity();
// story has nineteen bytes
assert_eq!(16, len);
// We can re-build a String out of ptr, len, and capacity. This is all
// unsafe because we are responsible for making sure the components are
// valid:
let s = unsafe { String::from_raw_parts(ptr, len, capacity) };
assert_eq!(*story, s);
println!("Success!")
}
回复
1个回答
test
2024-07-08
https://play.rust-lang.org/?version=stable&mode=debug&edition...
error[E0596]: cannot borrow `story` as mutable, as it is not declared as mutable
--> src/main.rs:4:15
|
3 | let story = String::from("Rust By Practice");
| ----- help: consider changing this to be mutable: `mut story`
4 | let ptr = story.as_mut_ptr();
| ^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
经过 let mut story = mem::ManuallyDrop::new(story);
,story 已经不是一个 String ,而是一个 stuct std::mem::ManuallyDrop<String>。它的 new 是这样的:
pub const fn new(value: T) -> ManuallyDrop<T>
原来的 immutable 的 String ,被 move 进了 mut ManuallyDrop<String> 。
而 MuauallyDrop 实现了 trait DerefMut ,于是会发生 Deref Coercion:
If
T
implementsDerefMut<Target = U>
, andx
is a value of typeT
, then:
- In mutable contexts,
*x
(whereT
is neither a reference nor a raw pointer) is equivalent to*DerefMut::deref_mut(&mut x)
.- Values of type
&mut T
are coerced to values of type&mut U
T
implicitly implements all the (mutable) methods of the typeU
.
(这里,T
是 ManuallyDrop<String>
,U
是 String
)
于是你可以在 mut ManuallyDrop<String> 上调用所有 String 的 mutable methods。
回复
适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容