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

Rc解引用*s为何不返回引用?borrow与reference有何区别?

关于Rc解引用与借用的核心问题解答

这两个问题都触及了Rust中Deref trait和借用系统的关键逻辑,我来帮你逐一拆解:

1. 为何Rc值的*s不返回引用?

首先得明确Deref trait的实际工作流程:Rc<T>实现了Deref<Target = T>,它的deref方法确实会返回&T——也就是调用s.deref()能拿到指向内部String的&String引用。

但当你使用*操作符时,Rust会自动做一层展开:*s等价于*(s.deref())。这里对deref()返回的&String又执行了一次解引用,所以最终得到的是**String类型的值**,而非引用。

你之所以会预期返回引用,大概率是混淆了deref方法的返回值和*操作符的最终结果。如果想要获取&String,有几种更直接的写法:

  • 利用Deref强制转换:let o: &String = &s;(Rust会自动把&Rc<String>转为&String)
  • 显式调用deref:let o: &String = s.deref();
  • 先解引用再取引用:let o: &String = &*s;

而你最初的代码let o: &String = *s;报错,正是因为*s产生的是String类型,无法直接赋值给&String类型的变量。

2. Borrow(借用)和Reference(引用)是同一概念吗?

当然不是!二者是相关但完全不同的概念:

  • **Reference(引用)**是Rust中的一种类型,比如&T或&mut T,它代表对某个值的间接访问权限。
  • **Borrow(借用)**是一个动作,指的是创建引用的过程——当你获取一个值的引用时,你就是在“借用”这个值。

回到你遇到的cannot move out of borrowed content错误:当你写let o: String = *s;时,*s展开为*(s.deref()),而s.deref()返回的&String是一个通过借用得到的引用。Rust禁止从引用后移动值,因为移动会让原数据失效,而Rc是共享所有权类型,内部数据可能被多个实例共享,这种移动会破坏内存安全。

总结一下:借用是“获取引用”的行为,引用是这个行为产生的结果类型,二者不能混为一谈。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:42:07