当两者都有效时,为什么 Rust 编译器建议添加 '&' 而不是 '*'?

问题描述 投票:0回答:1

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

我可以说出两者都有效的原因:

  1. &
    有效,因为
    &wrapped
    属于
    &Ref<&i32>
    类型,可以将其取消引用强制转换为
    &&i32
    ,而可以将其取消引用强制转换为
    &i32
  2. *
    有效,因为
    *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

在报告的“帮助”中,建议我添加一个

&
。我想知道为什么它不建议我添加
*

rust dereference
1个回答
0
投票

&
在这里是一种更安全的选择,它总是有效,而
*
仅在所包含的类型实现
Copy
并且无论所包含的类型是否是引用
时才有效。如果推荐
Copy
的标准方法也能工作并生成相同的程序集,那么特殊的外壳“包含的是共享引用”(包括
&
)似乎没什么用。

© www.soinside.com 2019 - 2024. All rights reserved.