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

关于Rust函数传参自动解引用规则的常见疑问

我们已知String实现了Deref trait,解引用后可以得到&str,对应实现如下:

impl ops::Deref for String {
    type Target = str;

    #[inline]
    fn deref(&self) -> &str {
        unsafe { str::from_utf8_unchecked(&self.vec) }
    }
}
  • 如下代码可以正常运行,原因是符合Rust的自动解引用规则:当给需要&str参数的函数传入&String时,Rust会自动沿着&String -> &str的解引用链做隐式转换,类型完全匹配。
fn uppercase(s: &str) -> String {
    s.to_uppercase()
}

fn main() {
    let s = String::from("hello");
    assert_eq!(uppercase(&s), "HELLO");
}
  • 第二个代码片段无法运行的原因:
    自动解引用强制转换仅适用于引用类型之间的隐式转换,不会自动给所有权值取引用。你传入的实参是持有所有权的String类型值,而形参需要的是&str引用,Rust不会自动给String取引用再做解引用转换,因此类型不匹配,编译报错。
fn uppercase(s: &str) -> String {
    s.to_uppercase()
}

fn main() {
    let s = String::from("hello");
    assert_eq!(uppercase(s), "HELLO");
}
  • 第三个代码片段无法运行的原因:
    自动解引用只能做引用层面的无开销转换,不会隐式执行需要转移所有权或者拷贝数据的操作。你传入的实参是&String不可变引用,而形参需要拿到String的所有权,要把&String转成String需要手动执行解引用移动或者调用clone方法,这一步不会自动发生,因此类型不匹配,编译报错。
fn uppercase(s: String) -> String {
    s.to_uppercase()
}

fn main() {
    let s = String::from("hello");
    assert_eq!(uppercase(&s), "HELLO");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 02:27:02