[Rust] ์ฐธ์กฐ: Cow
Cow๋ Clone on Write(Copy on Write)์ ๋ํ ๋์์ ์ ๊ณตํ๋ enum ๊ธฐ๋ฐ ๊ตฌํ์ฒด๋ค.
์ผ๋ฐ์ ์ผ๋ก ๋ถ๋ณ ์ฐธ์กฐ์ ๋ํ ๊ฐ์ ๋ค๊ณ ์์ผ๋, write๋ฅผ ์๋ํ๋ฉด ๋ณต์ ๋ฅผ ์๋ํ ํ์ ๋ณ๊ฒฝ๋ ๋ณต์ ๋ณธ์ ๋ฐํํ๋ ํํ์ ๋์์ ์ ๊ณตํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก๋ ์ด๋ฐ ํํ๋ฅผ ๊ฐ์ง enum์ด๋ค.
ํ์์์๋ Borrowed๋ก ์ฐธ์กฐ๊ฐ๋ง์ ๋ค๊ณ ์๋ค๊ฐ, ์์ ์ด ๋ฐ์ํ๋ฉด ๋ณต์ ๋ณธ์ ๋ง๋ค์ด์ ๋ฐํํ๋ ๊ฒ์ด๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ํฌ๊ธฐ๊ฐ ํด ์ ์๋ ํ์
์ ๋ํด์ ์ฌ์ฉํ๊ธฐ ์ฉ์ดํ๋ค.
C++๋ C++11 ์ด์ ์๋ string์ด Cow ๊ธฐ๋ฐ ๊ตฌํ์ฒด์๋ ์ ์ด ์๋ค.
ํ๋ฒ ์ง์ Cow์ ์๊ฑด์ ๋ง์กฑํ๋ ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด์ ๋์ ๋ฐฉ์์ ํ์ธํด๋ณด์.
๋ด ๊ฒฝ์ฐ์๋ ๊ฐ๋จํ ๋ฌธ์์ด ๋ํผ๋ฅผ ๋ง๋ค์๋ค.
์ถ๋ ฅ๊ณผ ์ฌ์ค์ ๋ฉ์๋ ์ ๋๋ง ์ฑ์๋ฃ๊ณ
ToOwned ํธ๋ ์์ ๊ตฌํํ๋ค. Cow์ ๋ฃ์ผ๋ ค๋ฉด ์ด๊ฒ ํ์์กฐ๊ฑด์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ณต์ ๋ฅผ ํ์ธํ๊ธฐ ์ํด ๋ก๊ทธ๋ ํ์ค ์ฐ์๋ค.
๊ทธ๋ฆฌ๊ณ MyString->Cow๋ก์ ๋ณํ ๋์์ ๊ตฌํํ๋ค.
Borrowed๋ก ์ฐธ์กฐ๋ก ์ด๊ธฐ ์์ฑ์ ํ๋๋ก ํ๋ค. ๊ทธ๋ฌ์ง ์์ผ๋ฉด Cow๋ฅผ ์ฐ๋ ์๋ฏธ๊ฐ ์๋ค.
๊ทธ๋ฌ๊ณ ๋๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
Cow::from์ผ๋ก ์ฐธ์กฐ ๊ธฐ๋ฐ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ๊ทธ๋ฅ ๋ถ๋ณ ๋์์ผ๋ก ์ธ ๋๋ ๋์ถฉ ์ฐ๋ค๊ฐ, ์์ ๋์์ด ํ์ํ๋ฉด to_mut๋ก mutable ์ฐธ์กฐ๋ฅผ ๋ฐ์์ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
to_mut ์์ ์ ์์ฑ๋๋ mutable ์ฐธ์กฐ๋ ์๋ณธ ๊ฐ์ฒด์๋ ๋ฌด๊ดํ๋ฉฐ, to_owned๋ก ๋ณต์ ๋ ์ ๊ฐ์ฒด์ผ ๋ฟ์ด๋ค.
์ค์ ๋ก ๋๋ ค๋ด๋ ์๋ํ๋๋ก ์ฐํ ๊ฒ์ด๋ค.
์๋๋ ์ ์ฒด ์ฝ๋๋ค.
use std::borrow::Cow;
struct MyString(pub String);
impl MyString {
fn show(&self) {
println!("{}", self.0);
}
fn reset(&mut self, s: &str) {
self.0.clear();
self.0.push_str(s);
}
}
impl ToOwned for MyString {
type Owned = MyString;
fn to_owned(&self) -> MyString {
println!("๋ณต์ ๋จ");
MyString(self.0.clone())
}
}
impl<'a> From<&'a MyString> for Cow<'a, MyString> {
fn from(s: &'a MyString) -> Cow<'a, MyString> {
Cow::Borrowed(s)
}
}
fn main() {
let big_str = MyString("very big string".to_string());
let input = Cow::from(&big_str);
input.show();
println!("big_str: {:?}", big_str.0);
let mut input = Cow::from(&big_str);
{
let big_str_2 = input.to_mut();
big_str_2.reset("reset string");
println!("big_str_2: {:?}", big_str_2.0);
}
input.show();
println!("big_str: {:?}", big_str.0);
}์ฐธ์กฐ
https://doc.rust-lang.org/std/borrow/enum.Cow.html
https://dhghomon.github.io/easy_rust/Chapter_42.html