You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Rust编译器在&和*均可行时,建议添加&而非*?

为什么Rust编译器对print_number(wrapped)只建议添加&而非*?

先看你提供的可编译代码:

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); // 也可行
}

当你尝试直接调用print_number(wrapped)时,编译器报错却只提示添加&,但其实加*也能解决问题,核心原因在于编译器错误提示的优先级和常见使用场景的适配:

  • 编译器优先匹配最常规的智能指针使用路径
    Ref<T>是一个智能指针,Rust中对智能指针的常规用法是通过引用它来触发自动Deref转换。&wrapped的类型是&Ref<&i32>,编译器会自动通过Deref trait将其转换为&&i32,再进一步隐式解引用为&i32——这是最符合Rust开发者使用习惯的路径,所以编译器优先给出这个修复建议。

  • *wrapped的转换路径不在编译器优先提示的范围内
    虽然*wrapped确实能得到&i32(*wrapped等价于*Deref::deref(&wrapped),最终从&&i32解引用为&i32),但这条路径相对来说不是最“直观”的常规操作。编译器的错误提示逻辑是基于预设的常见修复模式,它不会遍历所有可能的正确修改方式,只会给出最普遍、最容易被开发者理解的方案。

  • 编译器提示的局限性
    Rust编译器的错误提示旨在解决最常见的问题,而非穷尽所有可行方案。它会优先选择语法修改最小、符合常规范式的建议,而&wrapped恰好是这种场景下的典型正确用法。

简单来说,两种方式都正确,但编译器只会优先提示更符合常规使用习惯的那一种。

内容的提问来源于stack exchange,提问作者Yan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:23:10