pub enum Cow<'a, B>where
B: ToOwned + ?Sized + 'a,{
Borrowed(&'a B),
Owned(<B as ToOwned>::Owned),
}
Expand description
写时克隆智能指针。
Cow
类型是一种智能指针,提供了写时克隆功能:它可以封装并提供对借用数据的不可变访问,并在需要可变的或所有权时懒惰地克隆数据。
该类型旨在通过 Borrow
trait 处理常规借用数据。
Cow
实现了 Deref
,这意味着您可以直接在它包含的数据上调用非可变方法。
如果需要进行可变的,则 to_mut
将获得一个拥有值的变量引用,必要时进行克隆。
如果需要引用计数指针,请注意 Rc::make_mut
和 Arc::make_mut
也可以提供写时克隆功能。
Examples
use std::borrow::Cow;
fn abs_all(input: &mut Cow<'_, [i32]>) {
for i in 0..input.len() {
let v = input[i];
if v < 0 {
// 如果尚未拥有,则克隆到 vector 中。
input.to_mut()[i] = -v;
}
}
}
// 因为 `input` 不需要可变的,所以不会发生克隆。
let slice = [0, 1, 2];
let mut input = Cow::from(&slice[..]);
abs_all(&mut input);
// 发生克隆是因为需要对 `input` 进行可变的。
let slice = [-1, 0, 1];
let mut input = Cow::from(&slice[..]);
abs_all(&mut input);
// 因为 `input` 已被拥有,所以不会发生克隆。
let mut input = Cow::from(vec![-1, 0, 1]);
abs_all(&mut input);
Run另一个示例显示如何将 Cow
保留在结构体中:
use std::borrow::Cow;
struct Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> {
values: Cow<'a, [X]>,
}
impl<'a, X: Clone + 'a> Items<'a, X> where [X]: ToOwned<Owned = Vec<X>> {
fn new(v: Cow<'a, [X]>) -> Self {
Items { values: v }
}
}
// 根据切片的借用值创建容器
let readonly = [1, 2];
let borrowed = Items::new((&readonly[..]).into());
match borrowed {
Items { values: Cow::Borrowed(b) } => println!("borrowed {b:?}"),
_ => panic!("expect borrowed value"),
}
let mut clone_on_write = borrowed;
// 将切片中的数据可变的为拥有的 vec,并在顶部推入新值
clone_on_write.values.to_mut().push(3);
println!("clone_on_write = {:?}", clone_on_write.values);
// 数据被可变的。让我们来看看。
match clone_on_write {
Items { values: Cow::Owned(_) } => println!("clone_on_write contains owned data"),
_ => panic!("expect owned data"),
}
RunVariants§
Implementations§
source§impl<B: ?Sized + ToOwned> Cow<'_, B>
impl<B: ?Sized + ToOwned> Cow<'_, B>
const: unstable · sourcepub fn is_borrowed(&self) -> bool
🔬This is a nightly-only experimental API. (cow_is_borrowed
#65143)
pub fn is_borrowed(&self) -> bool
cow_is_borrowed
#65143)const: unstable · sourcepub fn is_owned(&self) -> bool
🔬This is a nightly-only experimental API. (cow_is_borrowed
#65143)
pub fn is_owned(&self) -> bool
cow_is_borrowed
#65143)sourcepub fn into_owned(self) -> <B as ToOwned>::Owned
pub fn into_owned(self) -> <B as ToOwned>::Owned
提取拥有的数据。
如果数据尚未拥有,则克隆数据
Examples
在 Cow::Borrowed
上调用 into_owned
会返回借用数据的克隆:
use std::borrow::Cow;
let s = "Hello world!";
let cow = Cow::Borrowed(s);
assert_eq!(
cow.into_owned(),
String::from(s)
);
Run在 Cow::Owned
上调用 into_owned
会返回拥有所有权的数据。
数据被移出 Cow
而不被克隆。
use std::borrow::Cow;
let s = "Hello world!";
let cow: Cow<'_, str> = Cow::Owned(String::from(s));
assert_eq!(
cow.into_owned(),
String::from(s)
);
RunTrait Implementations§
1.14.0 · source§impl<'a> AddAssign<&'a str> for Cow<'a, str>
impl<'a> AddAssign<&'a str> for Cow<'a, str>
source§fn add_assign(&mut self, rhs: &'a str)
fn add_assign(&mut self, rhs: &'a str)
执行
+=
操作。 Read more1.19.0 · source§impl<'a> Extend<Cow<'a, str>> for String
impl<'a> Extend<Cow<'a, str>> for String
1.45.0 · source§impl From<Cow<'_, str>> for Box<str>
impl From<Cow<'_, str>> for Box<str>
source§fn from(cow: Cow<'_, str>) -> Box<str>
fn from(cow: Cow<'_, str>) -> Box<str>
将 Cow<'_, str>
转换为 Box<str>
当 cow
是 Cow::Borrowed
变体时,此转换在堆上分配并复制底层 str
。
否则,它将尝试重用拥有所有权的 String
的分配。
Examples
use std::borrow::Cow;
let unboxed = Cow::Borrowed("hello");
let boxed: Box<str> = Box::from(unboxed);
println!("{boxed}");
Runlet unboxed = Cow::Owned("hello".to_string());
let boxed: Box<str> = Box::from(unboxed);
println!("{boxed}");
Run1.45.0 · source§impl<'a, B> From<Cow<'a, B>> for Arc<B>where
B: ToOwned + ?Sized,
Arc<B>: From<&'a B> + From<B::Owned>,
impl<'a, B> From<Cow<'a, B>> for Arc<B>where B: ToOwned + ?Sized, Arc<B>: From<&'a B> + From<B::Owned>,
1.45.0 · source§impl<'a, B> From<Cow<'a, B>> for Rc<B>where
B: ToOwned + ?Sized,
Rc<B>: From<&'a B> + From<B::Owned>,
impl<'a, B> From<Cow<'a, B>> for Rc<B>where B: ToOwned + ?Sized, Rc<B>: From<&'a B> + From<B::Owned>,
1.22.0 · source§impl<'a> From<Cow<'a, str>> for Box<dyn Error>
impl<'a> From<Cow<'a, str>> for Box<dyn Error>
1.22.0 · source§impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a>
impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a>
source§fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a>
fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a>
将 Cow
转换为 Dyn Error
+ Send
+ Sync
的 box。
Examples
use std::error::Error;
use std::mem;
use std::borrow::Cow;
let a_cow_str_error = Cow::from("a str error");
let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
assert!(
mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
Runsource§impl<'a, 'b, B, C> PartialEq<Cow<'b, C>> for Cow<'a, B>where
B: PartialEq<C> + ToOwned + ?Sized,
C: ToOwned + ?Sized,
impl<'a, 'b, B, C> PartialEq<Cow<'b, C>> for Cow<'a, B>where B: PartialEq<C> + ToOwned + ?Sized, C: ToOwned + ?Sized,
source§impl<'a, B> PartialOrd<Cow<'a, B>> for Cow<'a, B>where
B: PartialOrd + ToOwned + ?Sized,
impl<'a, B> PartialOrd<Cow<'a, B>> for Cow<'a, B>where B: PartialOrd + ToOwned + ?Sized,
impl<B> Eq for Cow<'_, B>where B: Eq + ToOwned + ?Sized,
Auto Trait Implementations§
impl<'a, B: ?Sized> RefUnwindSafe for Cow<'a, B>where B: RefUnwindSafe, <B as ToOwned>::Owned: RefUnwindSafe,
impl<'a, B: ?Sized> Send for Cow<'a, B>where B: Sync, <B as ToOwned>::Owned: Send,
impl<'a, B: ?Sized> Sync for Cow<'a, B>where B: Sync, <B as ToOwned>::Owned: Sync,
impl<'a, B: ?Sized> Unpin for Cow<'a, B>where <B as ToOwned>::Owned: Unpin,
impl<'a, B: ?Sized> UnwindSafe for Cow<'a, B>where B: RefUnwindSafe, <B as ToOwned>::Owned: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
从拥有的值中借用。 Read more