Rust开发之——引用与借用(11)

一 概述

  • 引用的基本概念
  • 可变引用(&mut)与不可变引用(&)
  • 悬垂引用
  • 引用规则总结

二 引用的基本概念

2.1 引用语法与借用

1
2
3
4
5
6
7
8
9
10
11
1、概念
用&符号创建引用,允许使用值但不获取所有权,避免数据移动。

2、示例:

fn calculate_length(s: &String) -> usize { s.len() }
let s1 = String::from("hello");
let len = calculate_length(&s1); // 传递引用而非值

3、借用概念:
获取引用称为 “借用”,如同借用他人物品,使用后无需归还所有权(因未拥有)

2.2 引用与所有权的关系

1
2
-引用不转移所有权,原变量仍拥有数据,离开作用域时数据仍会被丢弃。
-适用于需要多次使用同一数据但不想重复转移所有权的场景。

三 可变引用(&mut)与不可变引用(&)

3.1 可变引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1、语法:
用&mut创建,允许修改引用的数据。

2、示例:

fn change(some_string: &mut String) {
some_string.push_str(", world");
}
let mut s = String::from("hello");
change(&mut s); // 传递可变引用

3、限制:
-同一作用域内,同一数据最多有一个可变引用(避免数据竞争)。
-存在不可变引用时,无法创建可变引用。

3.2 不可变引用

1
2
3
4
5
6
7
8
1、语法:
用&创建,仅能读取数据,不能修改。

2、示例:
let r1 = &s; let r2 = &s;(多个不可变引用允许)。

3、限制:
存在可变引用时,无法创建不可变引用。

3.3 数据竞争预防

1
2
Rust 通过编译时检查避免数据竞争
(需满足三个条件:多指针访问、至少一个写入、无同步机制),确保内存安全。

四 悬垂引用

1
2
3
4
5
6
7
8
9
10
11
12
13
1、定义:
指向已释放内存的指针,其他语言中易出现,Rust 通过编译时检查杜绝。

2、示例错误:

fn dangle() -> &String {
let s = String::from("hello");
&s // 错误:s离开作用域后引用无效
}


3、解决方案:
直接返回值(如String)而非引用,转移所有权而非借用1、

五 引用规则总结

1
2
3
4
5
1、同一时间:
要么只有一个可变引用(&mut),要么只有多个不可变引用(&)。

2、引用有效性:
编译器确保引用始终指向有效数据,避免悬垂引用

六 参考

  • Rust中文官网——引用与借用