// 定义 SubContainer 结构体
struct SubContainer {
data: Vec<i32>,
}
// 定义 Container 结构体
struct Container {
data: Vec<i32>,
}
// split 函数,接收 Container 的可变引用,根据某个条件分割数据
fn split(container: &mut Container) -> (SubContainer, SubContainer) {
// 这里简单以数据长度的一半作为分割条件
let mid = container.data.len() / 2;
let (left, right) = container.data.split_at_mut(mid);
(
SubContainer { data: left.to_vec() },
SubContainer { data: right.to_vec() },
)
}
引用、所有权变化及避免借用检查错误说明:
- 引用:
split
函数接收 Container
的可变引用 &mut Container
,这意味着函数可以修改 Container
实例内部的数据,但不会获取所有权。
- 所有权:
Container
实例原本拥有 Vec<i32>
的所有权。
- 在
split
函数中,通过 split_at_mut
方法对 Vec<i32>
进行了分割。这个方法返回两个可变切片 &mut [i32]
,但并没有改变 Vec<i32>
的所有权。
- 随后,通过
to_vec
方法将切片转换为新的 Vec<i32>
,新的 Vec<i32>
由 SubContainer
结构体拥有。此时,原始 Container
中的 Vec<i32>
数据被转移到了两个新的 SubContainer
实例中,Container
不再拥有 Vec<i32>
的所有权。
- 避免借用检查错误:
- 在 Rust 中,借用检查器确保同一时间内,一个资源要么有一个可变引用(可写),要么有多个不可变引用(可读),但不能同时存在可变和不可变引用。
- 在这个例子中,通过
split_at_mut
方法获取的两个可变切片 left
和 right
是对 container.data
的唯一访问方式,不会出现同时存在其他对 container.data
的引用的情况,从而避免了借用检查错误。同时,to_vec
方法消耗了切片,进一步确保不会出现悬空引用等问题。