์ผ๋ฐ ํฌ์ธํฐ๋ ๋จ์ํ ๋ฐ์ดํฐ์ ์ฃผ์๋ฅผ ๊ฐ์ง๋ ํ์ ์ด์ง๋ง, ์ค๋งํธ ํฌ์ธํฐ๋ ๊ฐ๋ฆฌํค๋ ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ๋ฉํ๋ฐ์ดํฐ๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ์ค์ํฉ๋๋ค. ์ค๋งํธ ํฌ์ธํฐ๋ ํธ๋ ์ดํธ์ ์ ๋ค๋ฆญ์ ํ์ฉํด์ ๊ตฌํ๋๊ธฐ ๋๋ฌธ์ ์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ ํ์ฉํ๊ธฐ ์ํด์๋ ํธ๋ ์ดํธ์ ์ ๋ค๋ฆญ์ ์ ์ดํดํ ํ์๊ฐ ์์ต๋๋ค.
์ค๋งํธ ํฌ์ธํฐ๋ ์ฌ์ค์ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ์ฒด์ ๋๋ค. ํ์ง๋ง ๋ค์ 2๊ฐ์ ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์๋์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ํ ์ ์๊ฒ๋๋ ๊ฒ์ ๋๋ค.
- Deref ํธ๋ ์ดํธ: ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ ๋ ํผ๋ฐ์ค๋ฅผ ์ฝ์ด์ ์๋ณธ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ฒ์ด ์ญ์ฐธ์กฐ(Dereference)์ ๋๋ค. ์ด๋ฐ ์ค๋งํธ ํฌ์ธํฐ๋ ์ฌ์ค์ ๊ตฌ์กฐ์ฒด๋ผ๊ณ ๋ง์๋๋ ธ์ต๋๋ค. ๊ตฌ์กฐ์ฒด๋ ํฌ์ธํฐ๊ฐ ์๋๋ ๊ตฌ์กฐ์ฒด๋ฅผ ํตํด์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ค๋ฉด ๋ญ๊ฐ ์ถ๊ฐ์ ์ธ ๊ตฌํ์ด ํ์ํ๊ฒ ์ง์. ์ด๊ฒ ๋ฐ๋ก Deref ํธ๋ ์ดํธ์ ๋๋ค. *์ ๊ฐ์ ์ญ์ฐธ์กฐ ์ฐ์ฐ์๋ฅผ ์ค๋งํธ ํฌ์ธํฐ์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋๋ค. ์ ์ ํ์ ์ง์ ๊ตฌํํด๋ณด๋ฉด์ ๋ค์ ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค.
- Drop ํธ๋ ์ดํธ: ์ค๋งํธ ํฌ์ธํฐ๋ ์์ ์ ์ค์ฝํ๋ฅผ ๋ฒ์ด๋๊ฒ๋๋ฉด ์๋์ผ๋ก ํด์ง๋์ด์ผํฉ๋๋ค. ๋ฌ์คํธ๋ ์ค๋งํธ ํฌ์ธํฐ๊ฐ ์ค์ฝํ๋ฅผ ๋ฒ์ด๋๋ฉด Drop ํธ๋ ์ดํธ์ drop ๋ฉ์๋๋ฅผ ํธ์ถํด์ ์ค๋งํธ ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฐ์ดํฐ๋ฅผ ํด์งํฉ๋๋ค. ๊ทธ ์ธ์๋ ํ์ผ์ ๋ซ๊ฑฐ๋ํ๋ ์์ ์ ๋ฆฌ ๊ธฐ๋ฅ๋ค์ ์คํํ ์๋ ์์ต๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ์ ์ ํ์ ์ง์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
์ค๋งํธ ํฌ์ธํฐ ํ์
์ด ์ฌ๋ฌ๊ฐ์ง๊ฐ ์์ต๋๋ค๋ง ๊ฐ์ฅ ํต์ฌ์ ์ธ ์ค๋งํธ ํฌ์ธํฐ๋ Box<T>
ํ์
์
๋๋ค. <T>
๋ผ๋ ํ์๋ ์ด ๋ฐ์ดํฐ ํ์
๋ด๋ถ์ ์ ์ฅ๋๋ ํ์
์ด ์ ๋ค๋ฆญ ํ์
์ด๋ผ๋ ๊ฒ์
๋๋ค. ์์ ์ด ์ํ๋ ์ด๋ค ๋ฐ์ดํฐ ํ์
๋ ์ ์ฅํ ์ ์๋ค๋ ์๋ฏธ์
๋๋ค.
Box<T>
์ ๊ฐ์ฅ ํต์ฌ์ ์ธ ์ญํ ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ์์ญ์ ์ ์ฅํ๋ค๋ ๊ฒ์
๋๋ค. ์ฌ๊ธฐ์์ ๋ฌ์คํธ ์ธ์ด์์ ์์ฃผ ์ค์ํ ๊ฐ๋
์ด ๋์ต๋๋ค. ๋ฌ์คํธ ์ธ์ด๋ก ๊ฐ๋ฐํ๊ธฐ์ํด์๋ ๋ฐ์ดํฐ๊ฐ ํ ์์ญ์ ์ ์ฅ๋๋๋ ์คํ ์์ญ์ ์ ์ฅ๋๋๋๋ฅผ ํญ์ ์๊ฐํด์ผํฉ๋๋ค. ์คํ๊ณผ ํ ์์ญ์ ๋๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ด์ง๋ง ์์ฃผ ์ค์ํ ์ฐจ์ด์ ์ ๊ฐ์ง๊ณ ์์ต๋๋ค.
- ์คํ ์์ญ: ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ ์ปดํ์ผ ์์ ์ ์ ์ ์์ด์ผํฉ๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ํจ์ ํธ์ถ์ ๊ดํ ์คํ ํ๋ ์์ ๋ง๋๋ ์ปดํ์ผ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ ๋ณํ ์ ์์ต๋๋ค. ๋ง์ฝ ์คํ์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ๋์ด๋๋ค๋ฉด ์คํ ํ๋ ์์ ๋ง๊ฐ์ ธ๋ฒ๋ฆด ๊ฒ์ ๋๋ค. ๋ํ์ ์ผ๋ก u32๊ฐ์ ๊ธฐ๋ณธ ํ์ ๋ค์ ํญ์ ํฌ๊ธฐ๊ฐ ๊ณ ์ ๋์ด์์ต๋๋ค. ๋ฐ๋ผ์ ๋ฐ๋ก ์คํ์ ์ ์ฅ๋ ์ ์์ต๋๋ค.
- ํ ์์ญ: ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ฅผ ์ปดํ์ผ๋ฌ๊ฐ ์ ์ ์๊ณ , ํ๋ก๊ทธ๋จ์ด ๋์ํ๋ ์ค์ ๊ฒฐ์ ๋ฉ๋๋ค. ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ๋ฐ๋ ์ ์์ต๋๋ค.
์ด์ Box<T>์ ๋์ ๋ฐฉ์์ ์ดํดํ ์ ์์ต๋๋ค.
- ์์ ๊ถ ๊ด๋ฆฌ:
Box<T>
๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฐ์ดํฐ์ ํ์ ์ด ๋ฌด์์ด๋ ์๊ด์์ด ๋ฐ์ดํฐ๋ฅผ ํ ์์ญ์ ์ ์ฅํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์คํ์ ์ ์ฅํฉ๋๋ค. ์์ํ๊ฒ Box๋ผ๋ ๊ตฌ์กฐ์ฒด ํ์ ์ด ์์ ๊ฒ์ ๋๋ค. ์ด Box๋ผ๋ ๊ตฌ์กฐ์ฒดํ์ ์ ๊ฐ ํ๋๋ ๊ณ ์ ๋ ํฌ๊ธฐ๋ฅผ ๊ฐ์ง๋ ํ๋๋ค์ ๋๋ค. ๋ฐ๋ผ์ Box๋ผ๋ ๊ตฌ์กฐ์ฒด์ ๊ฐ์ฒด๋ ์คํ์ ์ ์ฅ๋ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ T๋ผ๋ ๋ฐ์ดํฐ๋ ํ ์์ญ์ ์ ์ฅํฉ๋๋ค. Box๋ T์ ํฌ์ธํฐ์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ Boxํ์ ์ ๊ฐ์ฒด์ ์์ ๊ถ์ด ์ด๋ํ๊ฒ๋๊ณ , ์ต์ข ์ ์ผ๋ก Box ๊ฐ์ฒด์ ์์ ๊ถ์ด ์ฌ๋ผ์ ธ์ ํด์ง๋ ๋ Drop ํธ๋ ์ดํธ๊ฐ ์ฌ์ฉ๋์ด์ Tํ์ ์ ๊ฐ์ฒด๋ ๊ฐ์ด ํด์ง๋๋ ๊ฒ์ ๋๋ค. - ๋ฉ๋ชจ๋ฆฌ ์ญ์ฐธ์กฐ: Box ๊ฐ์ฒด ์์ ํฌ์ธํฐ๊ฐ ๋ค์ด์์ ๊ฒ์ ๋๋ค. *๋ผ๋ ์ญ์ฐธ์กฐ ์ฐ์ฐ์๋ ์ฌ์ค ํฌ์ธํฐ ํ์ ์ ์ฌ์ฉํ๋ ๊ฒ์ ๋๋ค. Box๋ผ๋ ๊ตฌ์กฐ์ฒด์ ์ฌ์ฉํ๋ฉด ์๋ฌด๊ฒ๋ ์๋ฉ๋๋ค. ํ์ง๋ง Deref ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ๊ธฐ ๋๋ฌธ์ ์ญ์ฐธ์กฐ ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ์ ๋ Deref ํธ๋ ์ดํธ๋ฅผ ํตํด์ ํ ์์ญ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๋ ๊ฒ์ ๋๋ค.
์ฌ์ฉ๋ฒ์ ๊ฐ๋จํฉ๋๋ค. Box๋ผ๋ ๊ตฌ์กฐ์ฒด์ new ๋ฉ์๋์ ์์ ์ด ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋๊ฒ ๋ฟ์ ๋๋ค.
fn main() {
let my_data = Box::new(10);
println!("What is in the heap?: {}", my_data);
}
$ cargo run
Compiling pyalgo v0.1.0 (/Users/user/study/pyalgo)
Finished dev [unoptimized + debuginfo] target(s) in 0.88s
Running `target/debug/pyalgo`
What is in the heap?: 10
๊ทธ๋ผ my_data๋ผ๋ ์ค๋งํธ ํฌ์ธํฐ๊ฐ ๋ง๋ค์ด์ก์ต๋๋ค. my_data๋ผ๋ Box<i32>
ํ์
๊ตฌ์กฐ์ฒด๋ ์คํ์ ์์ฑ๋์๊ณ , 10์ด ์ ์ฅ๋ i32ํ์
๋ฐ์ดํฐ๋ ํ์ ์ ์ฅ๋์์ต๋๋ค. ํฌ๊ฒ ์ค์ํ๊ฑด ์๋์ง๋ง ํ๊ฐ์ง ๋ ์คํ์ ํด๋ณด๊ฒ ์ต๋๋ค. my_data๊ฐ ์คํ์ ์ ์ฅ๋์ด์๊ณ , i32ํ์
๋ฐ์ดํฐ๊ฐ ํ์ ์ ์ฅ๋์ด์๋ ๊ฒ์ ์ฆ๋ช
ํด๋ณด๊ฒ ์ต๋๋ค. ๋ค์ ์์ ๋ฅผ ์คํํด๋ณด๊ฒ ์ต๋๋ค.
fn main() {
let my_data = Box::new(10);
println!("What is in the heap?: {}", my_data);
println!("At stack: {:p}", &my_data);
println!("At heap: {:p}", my_data.as_ref());
}
$ cargo run
Compiling pyalgo v0.1.0 (/Users/user/study/pyalgo)
Finished dev [unoptimized + debuginfo] target(s) in 0.88s
Running `target/debug/pyalgo`
What is in the heap?: 10
At stack: 0x7ffef0c2e9b8
At heap: 0x5d21262e2b80
๊ฒฐ๊ณผ๊ฐ์ ๋ณด๋ฉด my_data๋ผ๋ ๋ณ์๊ฐ ์์นํ ๊ณณ์ ์ฃผ์๊ฐ์ด 0x7ffef0c2e9b8์ด๊ณ Box์ as_ref๋ฉ์๋๊ฐ ๋ฐํํ ๊ฐ์ด 0x5d21262e2b80์
๋๋ค. as_ref๋ ๋ฉ๋ด์ผ์ ์ฐพ์๋ณด๋ฉด Box<T>
์์ &T๋ฅผ ๋ฐํํ๋ค๊ณ ์จ์์ต๋๋ค. ํ์ ์ ์ฅ๋ ๋ฐ์ดํฐ์ ํฌ์ธํฐ๋ฅผ ๋ฐํํ๋ ๊ฒ์
๋๋ค. ๋ฆฌ๋
์ค์์๋ ์ด ๋ฉ๋ชจ๋ฆฌ ๊ฐ์ผ๋ก ํ์ธ์ง ์คํ์ธ์ง ํ์ธํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ์๋์๊ฐ์ด ์ดํ๋ฆฌ์ผ์ด์
์ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ถ๋ ฅํด๋ณผ ์ ์์ต๋๋ค.
$ cat /proc/$$/maps
563bb63d6000-563bb6404000 r--p 00000000 fc:02 16909610 /usr/bin/bash
563bb6404000-563bb64df000 r-xp 0002e000 fc:02 16909610 /usr/bin/bash
563bb64df000-563bb6518000 r--p 00109000 fc:02 16909610 /usr/bin/bash
563bb6518000-563bb651c000 r--p 00141000 fc:02 16909610 /usr/bin/bash
563bb651c000-563bb6525000 rw-p 00145000 fc:02 16909610 /usr/bin/bash
563bb6525000-563bb6530000 rw-p 00000000 00:00 0
563bb7090000-563bb71d1000 rw-p 00000000 00:00 0 [heap]
...์๋ต
7fffdb5c4000-7fffdb5e5000 rw-p 00000000 00:00 0 [stack]
7fffdb5f2000-7fffdb5f6000 r--p 00000000 00:00 0 [vvar]
7fffdb5f6000-7fffdb5f8000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
์ดํ๋ฆฌ์ผ์ด์ ๋ง๋ค ์ธ๋ถ ๊ฐ๋ค์ ๋ค๋ฅด์ง๋ง ์ ๊ฐ ์คํํ ์์ ์คํ ์์ญ์ ์ฃผ์๊ฐ์ 7fffdb5c4000-7fffdb5e5000์ด๊ณ , ํ ์์ญ์ ์ฃผ์๊ฐ์ 55fb3f245000-55fb3f4a9000์ธ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ๋ฌผ๋ก ์์ ์ ๋ฉ๋ชจ๋ฆฌ ์์ญ๊ณผ ์ ํํ ๊ฐ์ ๋ค๋ฅด๊ฒ ์ง๋ง, ๋ชจ๋ ์ดํ๋ฆฌ์ผ์ด์ ์ ์คํ ์์ญ์ ์ฃผ์๊ฐ์ด 0x7fff๋ก ์์ํ๊ณ ํ ์์ญ์ ์ฃผ์๊ฐ์ด 0x55fb๋ก ์์ํ๋ ๊ฒ์ ๋ค๋ฅด์ง ์์ ๊ฒ์ ๋๋ค. ์๋ํ๋ฉด ๋ฆฌ๋ ์ค ์ปค๋์ด ํ๋ก๊ทธ๋จ์ ์คํํ ๋ ๊ทธ๋ ๊ฒ ์ง์ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด์จ๋ ๊ฒฐ๋ก ์ ์ผ๋ก ์์ ๋ฅผ ์คํํด๋ณด๋ฉด Box๋ผ๋ ๋ฐ์ดํฐ ํ์ ์ ์คํ ์์ญ์ ์กด์ฌํ๊ณ , ํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฐ์ดํฐ๋ ํ ์์ญ์ ์กด์ฌํ๊ณ ์์์ ํ์ธํ ์ ์์ต๋๋ค.
Box<T>
๋ฅผ ์ ์ดํดํ๊ธฐ ์ํด์ ์์ฃผ ๋จ์ํ ์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ง์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค. Box<T>
๋ ๋ค์ํ ๋ฉ์๋๋ค์ด ์์ง๋ง, ์ฐ๋ฆฌ๋ ์ค๋งํธ ํฌ์ธํฐ์ ๊ฐ์ฅ ํต์ฌ ๊ธฐ๋ฅ์ธ ์ญ์ฐธ์กฐ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ํด์ง๋ง์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
// src/smart_pointer_basic/main.rs
use std::ops::{Deref, DerefMut};
struct MySmartPointer<T>(T);
impl<T> MySmartPointer<T> {
fn new(x: T) -> MySmartPointer<T> {
MySmartPointer(x)
}
}
impl<T> Deref for MySmartPointer<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
impl<T> DerefMut for MySmartPointer<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> Drop for MySmartPointer<T> {
fn drop(&mut self) {
println!("Dropping MySmartPointer");
}
}
fn main() {
let my_pointer = MySmartPointer::new(5);
println!("Value: {}", *my_pointer);
let mut mut_pointer = MySmartPointer::new(1);
*mut_pointer = 2;
println!("Value: {}", *mut_pointer);
}
$ cargo run --bin smart_pointer_basic
Compiling my-rust-book v0.1.0 (/home/gkim/study/my-rust-book)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
Running `target/debug/smart_pointer_basic`
Value: 5
Value: 2
Dropping MySmartPointer
Dropping MySmartPointer
๊ฐ์ฅ ๋จผ์ Deref, DerefMut ๋๊ฐ์ง ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ๋๋ก ์ ์ธํฉ๋๋ค.
use std::ops::{Deref, DerefMut};
๊ทธ๋ฆฌ๊ณ MySmartPointer๋ผ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค. ์ ๋ค๋ฆญ์ ์ฌ์ฉํด์ ์ ๋ค๋ฆญ ํ์ ์ T์ ๋๋ค. ๊ตฌ์กฐ์ฒด ์์ฒด๋ ๊ฐ์ฅ ๋จ์ํ๊ฒ ๋ฐ์ดํฐ๋ง ํฌํจํ๋๋ก ๋ง๋ญ๋๋ค.
struct MySmartPointer<T>(T);
์ฌ์ค์ ์ด ๊ตฌ์กฐ์ฒด๋ ์ค๋งํธํฌ์ธํฐ๊ฐ ์๋๋๋ค. ๋ฐ์ดํฐ๋ฅผ ํ์ ์ ์ฅํ๋๊ฒ ์๋๋ผ ์คํ์ ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ํ์ง๋ง ํ์ ๋ฉ๋ชจ๋ฆฌ ํ ๋นํ๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์๊ฐํ์ง์์์ผ๋ ํ๋ด๋ง ๋ด๊ธฐ ์ํด์ ์คํ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
MySmartPointer๋ฅผ ์์ฑํ๋ new ๋ฉ์๋๋ฅผ ๊ตฌํํฉ๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐ์ดํฐ x๋ฅผ ๋ฐ์์ ๊ทธ๋๋ก ์ ์ฅํ ๋ฟ์ ๋๋ค.
impl<T> MySmartPointer<T> {
fn new(x: T) -> MySmartPointer<T> {
MySmartPointer(x)
}
}
์ด์ Deref ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํฉ๋๋ค.
impl<T> Deref for MySmartPointer<T> {
type Target = T;
fn deref(&self) -> &T {
&self.0
}
}
deref๋ผ๋ ๋ฉ์๋๊ฐ ์๋๋ฐ ์ค๋งํธํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฐ์ดํฐ์ ๋ ํผ๋ฐ์ค๋ฅผ ๋ฐํํ๋๋ก ๊ตฌํํ๋ฉด ๋ฉ๋๋ค. ๊ทธ๋ฌ๋ฉด *์ฐ์ฐ์์ ๊ฒฐํจํด์ *&T๊ฐ ๋๋ฏ๋ก ๊ฒฐ๊ตญ ํ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ๋๋ ๊ฒ์ ๋๋ค.
๋ค์์ DerefMut ํธ๋ ์ดํธ์ ๋๋ค. mut์ด๋ผ๋ ์ด๋ฆ์ด ๋ถ์ ๊ฒ์์ ์ ์ ์๋ฏ์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ฟ ์ ์๋ mutable ๋ ํผ๋ฐ์ค &mut T๋ฅผ ๋ฐํํด์ค๋๋ค.
impl<T> DerefMut for MySmartPointer<T> {
fn deref_mut(&mut self) -> &mut T {
&mut self.0
}
}
DerefMutํธ๋ ์ดํธ์ ์ฌ์ฉ๋ฒ์ mainํจ์์์ ๋ณผ ์ ์์ต๋๋ค.
๋ค์์ Drop ํธ๋ ์ดํธ์ ๊ตฌํ์ ๋๋ค.
impl<T> Drop for MySmartPointer<T> {
fn drop(&mut self) {
println!("Dropping MySmartPointer");
}
}
์ฌ์ค ์ฐ๋ฆฌ ๋ฐ์ดํฐ๋ ์คํ์ ์ ์ฅ๋๋ฏ๋ก ์ค์ ๋ก ํ๋ ์ผ์ ์์ต๋๋ค. ๋ง์ฝ ๋ฉ๋ชจ๋ฆฌ ํ ๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ํ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ์ผ๋ฉด, drop ๋ฉ์๋์์ ๋ฉ๋ชจ๋ฆฌ ํด์ง๋ฅผ ํ๋ฉด ๋ฉ๋๋ค.
๋ค์์ mainํจ์๋ฅผ ๋ณด๊ฒ ์ต๋๋ค. ๋จผ์ Derefํธ๋ ์ดํธ๋ฅผ ์ด์ฉํด์ ์ค๋งํธํฌ์ธํฐ๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ๋ง ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
fn main() {
let my_pointer = MySmartPointer::new(5);
println!("Value: {}", *my_pointer);
my_pointer๋ ํฌ์ธํฐ์ ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก *์ฐ์ฐ์๋ฅผ ๋ถ์ด๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์์ต๋๋ค. ๋ง์ฝ Derefํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ์ง์์์ผ๋ฉด ๊ทธ๋ฅ ์ผ๋ฐ ๊ตฌ์กฐ์ฒด ์ด๋ฆ์ *๋ฅผ ๋ถ์ธ ๊ฒ์ด๋ฏ๋ก ์๋ฌด ๋์๋ ํ์ง ์์ ๊ฒ์ ๋๋ค.
๊ทธ ๋ค์์๋ DerefMut ํธ๋ ์ดํธ๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
let mut mut_pointer = MySmartPointer::new(1);
*mut_pointer = 2;
println!("Value: {}", *mut_pointer);
}
mut_pointer๋ผ๋ ๋ณ์๋ ๋ฐ์ดํฐ๊ฐ ๋ฐ๋ ๊ฒ์ด๋ฏ๋ก ๋ฐ๋์ mut ์ ์ธ์ด ์์ด์ผํฉ๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊พธ๋ ๋ฐฉ๋ฒ์ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํฉ๋๋ค. "*ํฌ์ธํฐ์ด๋ฆ" ํํ๋ก ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์ผ๋ก mainํจ์์ ์ค์ฝํ๊ฐ ๋๋๋ฉด ๋๊ฐ์ ์ค๋งํธํฌ์ธํธ๊ฐ ๋ชจ๋ ์ฌ๋ผ์ง๊ฒ ๋ฉ๋๋ค. ์ด๋ Drop ํธ๋ ์ดํธ์ drop ๋ฉ์๋๊ฐ ํธ์ถ๋ฉ๋๋ค.
์ค๋งํธ ํฌ์ธํฐ๋ ๋ฐ์ดํฐ๋ฅผ ํ ์์ญ์ ์ ์ฅํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค. ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ํฌ๊ฑฐ๋ ๋์ ์ผ๋ก ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ๋ณํ๋ค๋ฉด ์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํ ์๋ฐ์ ์์ต๋๋ค. ๋ํ์ ์ผ๋ก ๋คํธ์ํฌ๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๋ฐ์ดํฐ์ ํฌ๊ธฐ๋ ํด ๊ฒ์ด๊ณ , ๋ฐ์ดํฐ์ ํฌ๊ธฐ๊ฐ ์ผ๋ง๋๋ ์ง๋ ์ปดํ์ผ ์์ ์๋ ์ ๋ ์ ์ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ทธ ์ธ์ Box<T>
๋ผ๋ ํ์
์ ๋ฐ๋์ ์ฌ์ฉํด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ํ๋ ๋ ์์ต๋๋ค. ์ด์ ์ ํธ๋ ์ดํธ๋ฅผ ์ค๋ช
ํ ๋ ํธ๋ ์ดํธ ๊ฐ์ฒด์ ๋ํด์ ์ด์ผ๊ธฐํ์์ต๋๋ค. ๋ค์ ํ๋ฒ ์ด์ผ๊ธฐํ๋ฉด ์ด๋ค ํจ์๊ฐ ํน์ ํ ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ ํ์
๋ง์ ์ ๋ฌ๋ฐ์ ์ ์๋๋ก ๋ง๋๋ ๋ฐฉ๋ฒ์
๋๋ค. ์ฌ๋ฌ๊ฐ์ ๊ตฌ์กฐ์ฒด๊ฐ ์๋๋ฐ ๋ชจ๋ A๋ผ๋ ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ์ต๋๋ค. ๊ทธ๋ผ ์ด ๊ตฌ์กฐ์ฒด๋ค์ ๋ฒกํฐ๋ ๋ฐฐ์ด์ ๋ชจ์๋๊ณ ์ถ์ ๋๊ฐ ์์ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด์ GenSerialData๋ผ๋ ํน์ ํ ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ ํ์
๋ค์ ํ๋์ ๋ฒกํฐ์ ๋ชจ์์ ํ๊บผ๋ฒ์ ์ฒ๋ฆฌ๋๋๋ก ๋ง๋ค๊ณ ์ถ์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ง๋ค ์ ์์ต๋๋ค.
use std::io::{stdin, stdout, Write};
fn get_user_input() -> String {
let mut s = String::new();
let _ = stdout().flush();
stdin()
.read_line(&mut s)
.expect("Did not enter a correct string");
if let Some('\n') = s.chars().next_back() {
s.pop();
}
if let Some('\r') = s.chars().next_back() {
s.pop();
}
s
}
trait GenSerialData {
fn get_input(&mut self);
fn generate(&self) -> Option<&str>;
}
struct UserID {
digit: u32,
id: Option<String>,
}
impl GenSerialData for UserID {
fn get_input(&mut self) {
println!("Please input {}-digits User ID: ", self.digit);
self.id = Some(get_user_input());
}
fn generate(&self) -> Option<&str> {
self.id.as_ref().map(|x| x.as_str())
}
}
struct ProductID {
digit: u32,
id: Option<String>,
}
impl GenSerialData for ProductID {
fn get_input(&mut self) {
println!("Please input {}-digits Product ID: ", self.digit);
self.id = Some(get_user_input());
}
fn generate(&self) -> Option<&str> {
self.id.as_ref().map(|x| x.as_str())
}
}
fn collect_data(items: &mut [&dyn GenSerialData]) {
for item in items.iter_mut() {
item.get_input();
}
}
fn generate_serial(items: &[&dyn GenSerialData]) -> String {
let mut data = String::new();
for item in items.iter() {
data.push_str(item.generate().unwrap());
}
data
}
fn main() {
let userid = UserID { digit: 4, id: None };
let product = ProductID { digit: 8, id: None };
let mut items = [&userid, &product];
collect_data(&mut items);
let serial = generate_serial(&items);
println!("Serial generated: {}", serial);
}
$ cargo run --bin smart_pointer_application
Compiling my-rust-book v0.1.0 (/home/gkim/study/my-rust-book)
error[E0308]: mismatched types
--> src/smart_pointer_application/main.rs:73:31
|
73 | let mut items = [&userid, &product];
| ^^^^^^^^ expected `&UserID`, found `&ProductID`
|
= note: expected reference `&UserID`
found reference `&ProductID`
error[E0596]: cannot borrow `**item` as mutable, as it is behind a `&` reference
--> src/smart_pointer_application/main.rs:57:9
|
57 | item.get_input();
| ^^^^ cannot borrow as mutable
Some errors have detailed explanations: E0308, E0596.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `my-rust-book` (bin "smart_pointer_application") due to 2 previous errors
์ด ์์ ๋ ์ฌ์ฉ์ ID๊ณผ ์ ํ ID๋ฅผ ์กฐํฉํด์ ์ ํ์ ์๋ฆฌ์ผ๋ฒํธ๋ฅผ ๋ง๋๋ ์์ ์ ๋๋ค. UserID๋ผ๋ ๊ตฌ์กฐ์ฒด์ ProductID๋ผ๋ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค์์ต๋๋ค. ์ด ๋๊ฐ์ง ๊ตฌ์กฐ์ฒด๋ ๋๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ํ๋ก๊ทธ๋จ์ ์คํํ๋ ์ฌ์ฉ์๋ก๋ถํฐ (์๋ง๋ ์ ํ์ ๊ด๋ฆฌํ๋ ์์ ๋ถ์์ ์ง์๋ ๊ฒ ๊ฐ๋ค์) ์ ๋ ฅ์ ๋ฐ์์ ๋ฌธ์์ด๋ก ์ ์ฅํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ฆฌ์ผ ๋ฒํธ๋ฅผ ๋ง๋ค ๋ ์์ ์ ๊ฐ์ ๋ฐํํด์ฃผ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก GenSerialData๋ผ๋ ํธ๋ ์ดํธ๋ฅผ UserID์ ProductID๊ฐ ๊ตฌํํ ์ ์์ต๋๋ค. ๋์ค์ ์ฌ์ฉ์ID์ ์ ํID์ธ์๋ ์ ์ํํ์ ์ฌ์ฉ ๋ง๊ธฐ ๋ ์ง๋ ํ๋งค ๋ ์ง ๋ฑ ๋ค์ํ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์๋ฆฌ์ผ ๋ฒํธ์ ๋ฃ์ ์ ์๋๋ก ํ์ฅ์ด ๊ฐ๋ฅํฉ๋๋ค. ์๋ก์ด ๋ฐ์ดํฐ์ ํ์ ์ ๋ง๋ค๊ณ GenSerialData๋ผ๋ ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ๊ธฐ๋ง ํ๋ฉด ๋๋๊น์.
ํต์ฌ์ ์ธ ์ญํ ์ ํ๋ ํจ์๊ฐ ๋ฐ๋ก collect_data์ generate_serial ํจ์์ ๋๋ค.
fn collect_data(items: &mut [&dyn GenSerialData]) {
for item in items.iter_mut() {
item.get_input();
}
}
fn generate_serial(items: &[&dyn GenSerialData]) -> String {
let mut data = String::new();
for item in items.iter() {
data.push_str(item.generate().unwrap());
}
data
}
ํธ๋ ์ดํธ ๊ฐ์ฒด์ ๋ฐฐ์ด์ ์ ๋ฌ๋ฐ์์ ๋ชจ๋ ํธ๋ ์ดํธ ๊ฐ์ฒด์ ๊ณตํต ๋ฉ์๋ get_input๊ณผ generate๋ฅผ ํธ์ถํ๋ ํจ์์ ๋๋ค. ์๋ฆฌ์ผ ๋ฒํธ์ ๋ค์ด๊ฐ์ผ๋๋ ๋ชจ๋ ๋ฐ์ดํฐ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ํ๊บผ์ ์ ์ ๋ ฅํ๊ณ ์ถ๋ ฅํ๋ ๋ฃจํ๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ ๊ฐ์ค๋ฝ๊ฒ๋ ์ด ์์ ์ฝ๋๋ ๋น๋๋์ง ์์ต๋๋ค. userid์ productid์ ๋ ํผ๋ฐ์ค๋ฅผ ์ ์ฅํ๋ items์์ ๋น๋ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฐฐ์ด์ด๋ ๋ฒกํฐ๋ ๋์ผํ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ๋๋ค. ํ์ง๋ง ์ด ์์ ์์๋ ๋์ผํ ํ์ ์ ์ ์ฅํ๋๊ฒ ์๋๋ค. &userid๋ UserID ๊ตฌ์กฐ์ฒด ํ์ ์ ๋ ํผ๋ฐ์ค์ด๊ณ , &productid๋ ProductID์ ๋ ํผ๋ฐ์ค์ด๊ธฐ ๋๋ฌธ์ ์๋ก ๋ค๋ฅธ ํ์ ์ ๋๋ค. ํ๋์ ๋ฐฐ์ด์ ์ ์ฅ๋ ์ ์์ต๋๋ค. ๋น๋ก ๋ ๋ ํผ๋ฐ์ค๊ฐ ๋ชจ๋ ๊ฐ์ ํธ๋ ์ดํธ๋ฅผ ๊ตฌํํ ํ์ ์ ๋ ํผ๋ฐ์ค์ด์ง๋ง, ๋์ผํ ํ์ ์ ์๋๋๋ค. ๊ฐ์ ๋ฐ๋ก ํธ๋ ์ดํธ ๊ฐ์ฒด๋ก ์ฌ์ฉ๋ ์๋ ์์ง๋ง, ํ๋์ ๋ฐฐ์ด์ ์ ์ฅ๋ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ด ๋ ๊ฐ์ฒด๋ฅผ Box<T>
์ ๋ด๋๋ค๋ฉด ์ด์ผ๊ธฐ๋ ๋ฌ๋ผ์ง๋๋ค. ๋ฐฐ์ด์ ์ ์ฅ๋๋ ๊ฒ์ Boxํ์
์
๋๋ค. ๊ทธ๋ผ Box๋ฅผ ์ฌ์ฉํ๋๋ก ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค.
// src/smart_pointer_application/main.rs
use std::io::{stdin, stdout, Write};
fn get_user_input() -> String {
let mut s = String::new();
let _ = stdout().flush();
stdin()
.read_line(&mut s)
.expect("Did not enter a correct string");
if let Some('\n') = s.chars().next_back() {
s.pop();
}
if let Some('\r') = s.chars().next_back() {
s.pop();
}
s
}
trait GenSerialData {
fn get_input(&mut self);
fn generate(&self) -> Option<&str>;
}
struct UserID {
digit: u32,
id: Option<String>,
}
impl GenSerialData for UserID {
fn get_input(&mut self) {
println!("Please input {}-digits User ID: ", self.digit);
self.id = Some(get_user_input());
}
fn generate(&self) -> Option<&str> {
self.id.as_ref().map(|x| x.as_str())
}
}
struct ProductID {
digit: u32,
id: Option<String>,
}
impl GenSerialData for ProductID {
fn get_input(&mut self) {
println!("Please input {}-digits Product ID: ", self.digit);
self.id = Some(get_user_input());
}
fn generate(&self) -> Option<&str> {
self.id.as_ref().map(|x| x.as_str())
}
}
//fn collect_data(items: &mut Vec<Box<dyn GenSerialData>>) { // If you want to use Vec<Box<dyn GenSerialData>> in main function
fn collect_data(items: &mut [Box<dyn GenSerialData>]) {
for item in items.iter_mut() {
item.get_input();
}
}
// &[&dyn GenSerialData] is wrong!
//fn generate_serial(items: &Vec<Box<dyn GenSerialData>>) -> String { // If you want to use Vec<Box<dyn GenSerialData>> in main function
fn generate_serial(items: &[Box<dyn GenSerialData>]) -> String {
let mut data = String::new();
for item in items.iter() {
data.push_str(item.generate().unwrap());
}
data
}
fn main() {
println!("hello");
let userid = UserID { digit: 4, id: None };
let productid = ProductID { digit: 8, id: None };
// Vec<&dyn GenSerialData> is wrong!
//let mut items: Vec<Box<dyn GenSerialData>> = vec![Box::new(userid), Box::new(productid)];
let mut items: [Box<dyn GenSerialData>; 2] = [Box::new(userid), Box::new(productid)];
collect_data(&mut items);
let serial = generate_serial(&items);
println!("Serial generated: {}", serial);
}
$ cargo run --bin smart_pointer_application
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s
Running `target/debug/smart_pointer_application`
hello
Please input 4-digits User ID:
1234
Please input 8-digits Product ID:
qwerasdf
Serial generated: 1234qwerasdf
์ด์ ์์ ์์๋ ์๋์ ๊ฐ์ด ๋ฐฐ์ด์ ์ฌ์ฉํ์ต๋๋ค.
fn collect_data(items: &mut [&dyn GenSerialData]) {
...
fn generate_serial(items: &[&dyn GenSerialData]) -> String {
...
let mut items = [&userid, &product];
๋ฐฐ์ด์ ์ฌ์ฉํ๋ ๋ชจ๋ ํจ์ ์ธ์์ items ๋ณ์ ์ ์ธ ๋ถ๋ถ์ Box๋ก ๋ฐ๊ฟจ์ต๋๋ค.
fn collect_data(items: &mut [Box<dyn GenSerialData>]) {
...
fn generate_serial(items: &[Box<dyn GenSerialData>]) -> String {
...
let mut items: [Box<dyn GenSerialData>; 2] = [Box::new(userid), Box::new(productid)];
๊ทธ๋ฆฌ๊ณ items์ ๋ฐฐ์ด์ด ์๋๋ผ ๋ฒกํฐ๋ก ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ๋ฒกํฐ๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
fn collect_data(items: &mut Vec<Box<dyn GenSerialData>>) { // If you want to use Vec<Box<dyn GenSerialData>> in main function
...
fn generate_serial(items: &Vec<Box<dyn GenSerialData>>) -> String { // If you want to use Vec<Box<dyn GenSerialData>> in main function
...
let mut items: Vec<Box<dyn GenSerialData>> = vec![Box::new(userid), Box::new(productid)];
ํ๊ฐ์ง ์ฃผ์ํด์ผํ ๊ฒ์ด ํ์ ์ง์ ์ ๋ฐ๋์ ํด์ผํ๋ค๋ ๊ฒ์ ๋๋ค.
let mut items = vec![Box::new(userid), Box::new(productid)];
let mut items = [Box::new(userid), Box::new(productid)];
๋ง์ฝ ์์ ๊ฐ์ด ํ์ ์ง์ ์ ์ง์ด๋ค๋ฉด ์ปดํ์ผ๋ฌ๋ ๋ฐฐ์ด์ UserID ํ์ ์ ํฌ์ธํฐ๊ฐ ์ ์ฅ๋๋ ๊ฒ์ธ์ง, ProductID ํ์ ์ ํฌ์ธํฐ๊ฐ ์ ์ฅ๋์ด์ผํ๋ ๊ฒ์ธ์ง๋ฅผ ํ๋จํ ์ ์์ต๋๋ค. ๋ฐ๋์ ํธ๋ ์ดํธ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๋ค๊ณ ํ์ ์ ์จ์ฃผ์ด์ผํฉ๋๋ค.
๊ทธ ์ธ์๋ ๋ช๊ฐ์ง ์ค๋งํธ ํฌ์ธํฐ๊ฐ ๋ ์์ต๋๋ค. ๊ฐ๊ธฐ ๋ค๋ฅธ ์ฉ๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ํ์ง๋ง ๋ค๋ฅธ ์ค๋งํธ ํฌ์ธํฐ๋ค์ ๋ณดํต ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ด๋ ๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์์ ์ฌ์ฉ๋๋ ๊ฒ๋ค์ด๋ผ์ ์ด ์ฑ ์์๋ ์์ธํ ์๊ฐํ์ง ์๊ฒ ์ต๋๋ค. ๊ฐ๋จํ ์ด๋ฆ๊ณผ ์ฉ๋๋ง ์๊ฐํ๊ฒ ์ต๋๋ค.
Rc<T>
,Arc<T>
: ์์ ๊ถ์ ์ฌ๋ฌ๊ฐ ๋ง๋ค์ด์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์์ต๋๋ค.Rc<T>
๋ ์ฑ๊ธ์ฐ๋ ๋์์ ํธ๋ฆฌ๋ ๊ทธ๋ํ์ ๊ฐ์ด ์๋ก๊ฐ ์๋ก๋ฅผ ์ฐธ์กฐํ๋ ํํ์ ์ฌ์ฉํฉ๋๋ค.Arc<T>
๋ ๋ฉํฐ์ฐ๋ ๋์์ ์ฌ๋ฌ ์ฐ๋ ๋๊ฐ ๊ณต์ ํ๋ ๋ฐ์ดํฐ์ ์ฌ์ฉํฉ๋๋ค.RefCell<T>
: ์ด๋ค ๋ฐ์ดํฐ์ ๋ถ๋ณํ(Immutable) ๋ ํผ๋ฐ์ค๋ฅผ ๊ฐ์ง๊ณ ์๋ ์ํฉ์์๋, ๋ฐ์ดํฐ๋ฅผ ์์ ๊ฐ๋ฅํ๋๋ก ๋ง๋ค์ด์ค๋๋ค. ๋ณดํต์ ์์ ํ์ง ์์ง๋ง, ์ ๋ง ์์ธ์ ์ธ ๊ฒฝ์ฐ์ ์์ ๊ฐ๋ฅํ๋๋ก ๋ง๋ค์ด์ผ๋ ๋ ์ฌ์ฉํฉ๋๋ค.Cell<T>
: ๊ฑฐ์ ์ฌ์ฉ๋ ์ผ์ด ์์ง๋ง, ํน์ ๊ฐ์ฒด์ ๋ํด ์์ ํ ์์ ๊ฐ๋ฅํ๋ฉด์ ๋์์ ๊ณต์ ๊ฐ๋ฅํ ํฌ์ธํฐ๋ฅผ ๋ง๋ญ๋๋ค. ๋ณดํต C/C++ ์ธ์ด์ ๋ฌ์คํธ ์ธ์ด๋ฅผ ๊ฐ์ด ์ฌ์ฉํ ๋ C/C++์ ํฌ์ธํฐ ๋ณ์์ ์ ๊ทผํ๊ธฐ ์ํด ์ฌ์ฉํฉ๋๋ค.Mutex<T>
,RwLock<T>
: ์ด๋ฆ์์ ์ ์ ์๋ฏ์ด ๋ฝ์ ๊ตฌํํ ํ์ ๋ค์ ๋๋ค.