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

Rust中多共享引用如何安全访问非Copy/Clone类型值?

Rust引用底层机制:无Copy/Clone类型的访问问题

我是Rust新手,已读完《The Book》,希望深入理解该语言中引用的底层机制。

我知道引用是一种指针类型,解引用时会指向内存中的某个值:

let x = 5;
let y = &x;

在这个示例中,y是指向x内存地址的指针,因此y的类型和值与x不同:

assert_eq!(y, x);
// 编译失败,因为assert_eq!未实现`&{integer} == {integer}`的比较逻辑
  • 引用与其指向的值并非同一事物。

但使用*操作符对y解引用后,就能获取它指向的值,以下代码可以正常编译:

assert_eq!(*y, x);

不过解引用操作存在一个问题:如果将解引用后的值赋值给新变量,会触发所有权转移(对于未实现Copy trait的类型):

#[derive(Debug)]
struct Point { x: i32, y: i32 }

let x = Point {x:1, y:2};
let y = &x;
let z = *y;
// 编译失败,因为`*y`的类型为`Point`,未实现`Copy` trait,触发所有权转移
  • 为该类型实现Copy trait后,Rust会创建值的副本,并将副本的所有权转移给新变量,从而解决编译错误。

核心问题

对于未实现Copy或Clone trait的类型,Rust如何通过引用访问其值,同时避免解引用操作获取值的所有权,导致原变量的其他共享引用失效?

可运行示例

#[derive(Debug)]
struct Point { x: i32, y: i32 }

let x = Point {x:1, y:2};
let y = &x;
let z = &x;

fn print_point(a: &Point){
    println!("{a:#?}")
}

println!("Printing y");
print_point(y);
    
println!("Printing x");
println!("{x:#?}");

println!("Printing z");
print_point(z);

解决方案与原理

要避免解引用触发所有权转移,核心是不要将解引用后的值赋值给拥有所有权的新变量,而是通过以下方式基于引用直接访问值:

  1. 传递引用给函数
    示例中的print_point函数接收&Point类型的参数,传递的是引用本身的副本(引用默认实现了Copy trait),不会触及原值的所有权,因此原变量x和其他引用z都能正常使用。

  2. 利用自动解引用(Deref Coercion)访问内容
    Rust会自动处理引用的多层解引用,比如对于&Point类型的变量y,你可以直接写y.x来访问字段,无需手动写(*y).x。这种操作只是临时访问值的内容,不会转移所有权。

  3. 临时解引用用于操作而非赋值
    如果只是临时使用解引用后的值(比如作为打印参数、计算输入),而非赋值给新变量,也不会触发所有权转移。例如println!("{:#?}", *y),这里的*y是临时借用,执行完后所有权仍属于原变量。

本质上,Rust的借用规则保证了共享引用(&T)可以同时存在多个,只要不尝试获取原值的所有权,通过引用就能安全访问值的内容,同时维持内存安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 18:27:21