我用 Rust 编写了一个简单的程序。这个程序可以编译。
use std::cell::{Ref, RefCell};
fn print_number(x: &i32) {
println!("x is {}", x);
}
fn main() {
let stack: i32 = 42;
let reference: &i32 = &stack;
let refcell: RefCell<&i32> = RefCell::new(reference);
let wrapped: Ref<'_, &i32> = refcell.borrow();
print_number(&wrapped);
print_number(*wrapped);
}
我可以说出两者都有效的原因:
&
有效,因为 &wrapped
属于 &Ref<&i32>
类型,可以将其取消引用强制转换为 &&i32
,而可以将其取消引用强制转换为 &i32
。*
有效,因为 *wrapped
相当于 *Deref::deref(&wrapped)
。我们知道 Deref::deref(&Ref<&i32>)
结果为 &&i32
,因此 *Deref::deref(&Ref<&i32>)
结果为 *&&i32
,即 &i32
。第二种方法(使用
*
)似乎更直接,但是 Rust 编译器建议我使用第一种方法(使用 &
)。如果我添加一行:
print_number(wrapped);
这当然不能编译。但我对编译器报告感兴趣:
error[E0308]: mismatched types
--> src/main.rs:16:18
|
16 | print_number(wrapped);
| ------------ ^^^^^^^ expected `&i32`, found `Ref<'_, &i32>`
| |
| arguments to this function are incorrect
|
= note: expected reference `&i32`
found struct `Ref<'_, &i32>`
note: function defined here
--> src/main.rs:3:4
|
3 | fn print_number(x: &i32) {
| ^^^^^^^^^^^^ -------
help: consider borrowing here
|
16 | print_number(&wrapped);
| +
For more information about this error, try `rustc --explain E0308`.
error: could not compile `testrust` (bin "testrust") due to 1 previous error
在报告的“帮助”中,建议我添加一个
&
。我想知道为什么它不建议我添加 *
。
&
在这里是一种更安全的选择,它总是有效,而*
仅在所包含的类型实现Copy
并且无论所包含的类型是否是引用时才有效。如果推荐 Copy
的标准方法也能工作并生成相同的程序集,那么特殊的外壳“包含的是共享引用”(包括 &
)似乎没什么用。