Rust标准库提供了丰富的方法来安全地访问或转换数据的引用
borrow()
方法通常用于 RefCell<T>
类型,但也可以用于其他实现了 Deref
和 Borrow
trait 的类型。它返回一个不可变引用 &T
,用于在运行时动态检查借用规则。
.borrow()
获取的引用生命周期与调用者的作用域相同。use std::cell::RefCell;
let data = RefCell::new(5);
let borrow = data.borrow();
// let mut_borrow = data.borrow_mut(); // 这会panic
borrow_mut()
方法主要用于 RefCell<T>
,但也可以用于其他实现了 DerefMut
和 BorrowMut
trait 的类型。它用于获取可变引用 &mut T
,并在运行时检查借用规则,如果有任何现存的借用(不可变或可变),都会导致 panic。
use std::cell::RefCell;
let data = RefCell::new(5);
let mut borrow_mut = data.borrow_mut();
// let borrow = data.borrow(); // 这会panic
适用于 Option<T>
, Box<T>
, Vec<T>
等类型,用来获取内部数据的不可变引用 &T
,而不改变所有权。如果容器内部有值,则返回内部值的引用;如果为 None
,则返回 None
。
AsRef<T>
trait 来提供 .as_ref()
方法。let opt = Some(5);
if let Some(ref value) = opt.as_ref() {
println!("{}", value);
}
类似于 .as_ref()
,但用于获取可变引用 &mut T
。适用于 Option<T>
, Box<T>
等,当需要可变访问内部数据而不转移所有权时使用。
let mut opt = Some(5);
if let Some(ref mut value) = opt.as_mut() {
*value = 10;
}
通常用于访问 Vec
, HashMap
, BTreeMap
等集合类型中的元素。这两个方法提供了安全访问集合内元素的方式,尤其是在索引可能越界的情况下,相比直接使用索引操作符 [ ] 更加安全。由于需要进行边界检查,会有一定的性能开销。
None
。None
。let vec = vec![1, 2, 3];
if let Some(value) = vec.get(1) {
println!("{}", value);
}
用于获取原始指针(raw pointers)到容器的数据。
let vec = vec![1, 2, 3];
let ptr = vec.as_ptr();
用于迭代容器中的元素。适用于Vec, HashMap, HashSet, VecDeque等多种集合类型
let vec = vec![1, 2, 3];
for val in vec.iter() {
println!("{}", val);
}
适用于 Option<Box<T>>
或 Option<&T>
等类型,便捷地解引用获取内部的引用。
Option<&T>
。Option<&mut T>
。let opt = Some(Box::new(5));
if let Some(value) = opt.as_deref() {
println!("{}", value);
}
虽然不是直接获取引用的方法,但在处理 Option
或 Result
时非常有用。
Option
为 None
,返回默认值,否则映射内部值。Option
为 None
,调用提供的闭包并返回结果,否则映射内部值。let opt = Some(5);
let new_opt = opt.map(|x| x * 2);
let default = opt.map_or(0, |x| x * 2);
let computed_default = opt.map_or_else(|| 0, |x| x * 2);
适用于 Vec<T>
等集合,将其视为 &[T]
(不可变切片)或 &mut [T]
(可变切片)来访问。
let vec = vec![1, 2, 3];
let slice: &[i32] = vec.as_slice();
适用于 Vec
等集合,创建一个移除并迭代集合中元素的迭代器,同时修改原集合。
let mut vec = vec![1, 2, 3];
for elem in vec.drain(..) {
println!("{}", elem);
}
用于可变引用 &mut [T]
,将其分割成两个独立的可变引用。
let mut slice = &mut [1, 2, 3, 4];
let (left, right) = slice.split_at_mut(2);
虽然不是直接的引用获取方法,但在处理集合时非常有用。
.zip()可以将两个迭代器组合成一个,同时提供对两个集合元素的引用。
enumerate()为迭代器的每个元素附加一个索引,返回(usize, &T)或(usize, &mut T)。
let vec1 = vec![1, 2, 3];
let vec2 = vec![4, 5, 6];
for (a, b) in vec1.iter().zip(vec2.iter()) {
println!("{}, {}", a, b);
}
用于类型转换的trait方法,特别是当转换可能失败时(例如大小不匹配),它们提供了比直接转换更安全的选项,并且可以返回Result类型来处理错误。
use std::convert::TryInto;
let num: i32 = 5;
let result: Result<u8, _> = num.try_into();
简化 Option
处理,对于 Option<T>
当值为 None
时,使用 Default
trait 来提供一个默认值。
let opt: Option<i32> = None;
let value = opt.unwrap_or_default();