Cow
型 (clone-on-write の略) について。
以下の特徴を持つスマートポインタ。
※ 参照方式で to_mut
を呼ぶと、所有方式にするために参照先がクローンされる。
既定値なら参照で共有し、カスタム値に変化した場合にだけ所有にする。
既定値が多い場合、この方法はクローン時間とメモリの大幅な節約になる。
以下では、参照と所有それぞれの形態で読込と書込を行っている。
use std::borrow::Cow;
fn main() {
let mut cow1 = Cow::<i32>::Borrowed(&42);
let mut cow2 = Cow::<i32>::Owned(42);
assert_eq!(*cow1, 42);
assert_eq!(*cow2, 42);
*Cow::to_mut(&mut cow1) += 1;
*Cow::to_mut(&mut cow2) += 1;
assert_eq!(*cow1, 43);
assert_eq!(*cow2, 43);
}
以下では、text0
と text1
は既定値を共有して参照している。
そして、text2
と text3
はそれぞれ独自の値を所有している。
use std::borrow::Cow;
fn main() {
let text0 = &mut TextHolder::new();
let text1 = &mut TextHolder::new();
let text2 = &mut TextHolder::new();
let text3 = &mut TextHolder::new();
text2.add_em();
text3.set_custom("Custom text");
assert_eq!(text0.get(), "Default text");
assert_eq!(text1.get(), "Default text");
assert_eq!(text2.get(), "Default text!");
assert_eq!(text3.get(), "Custom text");
}
struct TextHolder(Cow<'static, str>);
impl TextHolder {
fn new() -> Self {
static TEXT: &str = "Default text";
Self(Cow::Borrowed(TEXT))
}
fn get(&self) -> &str {
&*self.0
}
fn add_em(&mut self) {
Cow::to_mut(&mut self.0).push_str("!");
}
fn set_custom(&mut self, value: &str) {
self.0 = Cow::Owned(value.to_string());
}
}