[][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