[−][src]Function tao_of_rust::ch05::smart_pointer::cow
pub fn cow()
智能指针和所有权: Cow写时复制
是一个枚举类型的智能指针,包括两个可选值:Borrowed,用于包裹引用,以及Owned,用于包裹所有者 一般用于读多写少的场景 Base usage: Cow
use std::borrow::Cow; fn abs_all(input: &mut Cow<[i32]>) { for i in 0..input.len() { let v = input[i]; if v < 0 { input.to_mut()[i] = -v; } } } fn abs_sum(ns: &[i32]) -> i32 { let mut lst = Cow::from(ns); abs_all(&mut lst); lst.iter().fold(0, |acc, &n| acc + n) } fn main() { // 这里没有可变需求,所以不会克隆 let s1 = [1,2,3]; let mut i1 = Cow::from(&s1[..]); abs_all(&mut i1); println!("IN: {:?}", s1); println!("OUT: {:?}", i1); // 这里有可变需求,所以会克隆 // 注意: 借用数据被克隆为了新的对象 // s2 != i2. 实际上, s2 不可变,也不会被改变 let s2 = [1,2,3, -45, 5]; let mut i2 = Cow::from(&s2[..]); abs_all(&mut i2); println!("IN: {:?}", s2); println!("OUT: {:?}", i2); // 这里不会克隆,因为数据本身拥有所有权 // 注意: 在本例中,v1是本身就是可变的 let mut v1 = Cow::from(vec![1,2,-3,4]); abs_all(&mut v1); println!("IN/OUT: {:?}", v1); //没有可变需求所以没有克隆 let s3 = [1,3,5,6]; let sum1 = abs_sum(&s3[..]); println!("{:?}", s3); println!("{}", sum1); // 这里有可变需求所以这里发生了克隆 let s4 = [1,-3,5,-6]; let sum2 = abs_sum(&s4[..]); println!("{:?}", s4); println!("{}", sum2); }Run
Base usage: 利用Cow来统一实现规范 还可以跨线程安全传递字符串切片
use std::borrow::Cow; use std::thread; #[derive(Debug)] struct Token<'a> { raw: Cow<'a, str>, } impl<'a> Token<'a> { pub fn new<S>(raw: S) -> Token<'a> where S: Into<Cow<'a, str>>, { Token { raw: raw.into() } } } fn main() { let token = Token::new("abc123"); let token = Token::new("api.example.io".to_string()); thread::spawn(move || { println!("token: {:?}", token); }).join().unwrap(); }Run
Base usage: 不使用Cow,字符串切片无法跨线程传递
fn main() { let raw = String::from("abc"); let s = &raw[..]; let token = Token::new(s); thread::spawn(move || { println!("token: {:?}", token); }).join().unwrap(); }Run