1-3. references borrowing
Day 6-8: References & Borrowing ์์ฝ
๐ฏ ํต์ฌ ๊ฐ๋
์ ํ์ํ๊ฐ?
Day 3-5์์ ๋ฐ๊ฒฌํ ๋ฌธ์ : ํจ์์ ๊ฐ์ ๋๊ธฐ๋ฉด ์์ ๊ถ์ด ์ด๋ โ ์๋ ๋ณ์ ์ฌ์ฉ ๋ถ๊ฐ
fn takes_ownership(s: String) { println!("{}", s); }
let s = String::from("hello");
takes_ownership(s);
// println!("{}", s); // โ ์์ ๊ถ ์ด๋๋จ!ํด๊ฒฐ์ฑ : ์์ ๊ถ์ ๋๊ธฐ์ง ์๊ณ ๋น๋ ค์ฃผ๊ธฐ(Borrowing)
๐ ๋ ์ข ๋ฅ์ ์ฐธ์กฐ
1. Immutable Reference (&T) โ ์ฝ๊ธฐ ์ ์ฉ
fn calculate_length(s: &String) -> usize {
s.len() // ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ
}
let s = String::from("hello");
let len = calculate_length(&s); // ๋น๋ ค์ค
println!("{}", s); // โ
์ฌ์ ํ ์ฌ์ฉ ๊ฐ๋ฅ2. Mutable Reference (&mut T) โ ์์ ๊ฐ๋ฅ
fn change(some_string: &mut String) {
some_string.push_str(", world"); // ์์ ๊ฐ๋ฅ
}
let mut s = String::from("hello"); // ์๋ณธ๋ mut์ด์ด์ผ ํจ!
change(&mut s); // mutable๋ก ๋น๋ ค์ค
println!("{}", s); // "hello, world"Python๊ณผ์ ์ฐจ์ด
| Python | Rust &T | Rust &mut T | |
|---|---|---|---|
| ์ฝ๊ธฐ | โ | โ | โ |
| ์์ | โ | โ | โ |
Python์ ์ฐธ์กฐ๋ฅผ ํตํด ๋ง์๋๋ก ์์ ๊ฐ๋ฅํ์ง๋ง, Rust๋ ๋ช
์์ ์ผ๋ก &mut์ ์จ์ผ๋ง ์์ ๊ฐ๋ฅ
๐ Borrowing ํต์ฌ ๊ท์น (2๊ฐ์ง)
๊ท์น 1: &mut T๋ ๋์์ 1๊ฐ๋ง
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s; // โ ๋ ๋ฒ์งธ mutable ์ฐธ์กฐ ๋ถ๊ฐ!
println!("{}, {}", r1, r2);์ด์ : ๋ ๊ณณ์์ ๋์์ ์์ ํ๋ฉด ๋ฐ์ดํฐ ์ถฉ๋
๊ท์น 2: &T์ &mut T ๋์ ์ฌ์ฉ ๋ถ๊ฐ
let mut s = String::from("hello");
let r1 = &s; // ๐ ์ฝ๊ธฐ
let r2 = &s; // ๐ ์ฝ๊ธฐ
let r3 = &mut s; // โ ์ฝ๋ ์ค์ ์์ ๋ถ๊ฐ!
println!("{}, {}, {}", r1, r2, r3);์ด์ : ์ฝ๋ ์ค์ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ํ
์์ธ: &T ์ฌ๋ฌ ๊ฐ๋ OK
let s = String::from("hello");
let r1 = &s; // โ
let r2 = &s; // โ
let r3 = &s; // โ
์ฝ๊ธฐ๋ผ๋ฆฌ๋ ์์ !๋์๊ด ๋น์
&T(์ฝ๊ธฐ) = ์ฌ๋ฌ ๋ช ์ด ๋์์ ์ฑ ์ฝ๊ธฐ โ OK&mut T(์์ ) = ํ ๋ช ๋ง ํ์ผ๋ก ์์ ๊ฐ๋ฅ โ ๋์์ ๋ ๋ช ๋ถ๊ฐ&T+&mut T= ์ฝ๋ ์ค์ ์์ โ ์ฝ๋ ๋ด์ฉ์ด ๋ฐ๋ ์ํ
๐ NLL (Non-Lexical Lifetimes)
Rust ์ปดํ์ผ๋ฌ๋ ์ฐธ์กฐ์ ๋ง์ง๋ง ์ฌ์ฉ ์์ ์ ๊ธฐ์ค์ผ๋ก ํ๋จ:
let mut s = String::from("hello");
let r1 = &s; // โโ r1 ์์
let r2 = &s; // โโ r2 ์์
println!("{}, {}", r1, r2); // โโ r1, r2 ๋ (๋ง์ง๋ง ์ฌ์ฉ)
let r3 = &mut s; // โ
r1, r2 ์ด๋ฏธ ๋๋ฌ์ผ๋ OK!
r3.push_str(", world");
println!("{}", r3);ํต์ฌ: ์ฝ๊ธฐ๊ฐ ๋๋ ํ ์์ ํ๋ ๊ฑด ์์ โ ์ปดํ์ผ๋ฌ๊ฐ ํ์ฉ
๐ Dangling Reference ๋ฐฉ์ง
// โ ํจ์ ๋ด๋ถ ๋ณ์์ ์ฐธ์กฐ๋ฅผ ๋ฐํ โ s๊ฐ drop๋๋ฉด ๋ฌดํจ!
fn dangle() -> &String {
let s = String::from("hello");
&s // s๊ฐ ํจ์ ๋์์ ์ฌ๋ผ์ง โ ๊ฐ๋ฆฌํฌ ๋์ ์์!
}
// โ
์์ ๊ถ ์์ฒด๋ฅผ ๋ฐํ
fn no_dangle() -> String {
let s = String::from("hello");
s // ์์ ๊ถ์ด ํธ์ถ์์๊ฒ ์ด๋
}C/C++์์๋ dangling pointer๊ฐ ๋ฐํ์ ๋ฒ๊ทธ๋ก ์ด์ด์ง์ง๋ง, Rust๋ ์ปดํ์ผ ๋จ๊ณ์์ ์ฐจ๋จ
๐ ์ค์ ํจํด: ํจ์์์์ Borrowing
fn average(scores: &Vec<f64>) -> f64 { // & โ ์ฝ๊ธฐ๋ง
let sum = scores.iter().sum::<f64>();
sum / scores.len() as f64
}
fn highest(scores: &Vec<f64>) -> f64 { // & โ ์ฝ๊ธฐ๋ง
*scores.iter()
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap()
}
fn add_score(scores: &mut Vec<f64>, score: f64) { // &mut โ ์์ ํ์
scores.push(score);
}
fn main() {
let mut scores = vec![85.0, 92.0, 78.0, 95.0, 88.0];
println!("ํ๊ท : {}", average(&scores)); // ์ฝ๊ธฐ
println!("์ต๊ณ : {}", highest(&scores)); // ์ฝ๊ธฐ
add_score(&mut scores, 100.0); // ์์
println!("์ถ๊ฐ ํ ํ๊ท : {}", average(&scores)); // ๋ค์ ์ฝ๊ธฐ
println!("์ ์ฒด ์ ์: {:?}", scores); // ์์ ๊ถ ์ ์ง๋จ!
}์์น: ์์ ์ด ํ์ํ ํจ์๋ง &mut, ๋๋จธ์ง๋ &๋ก ์ต์ ๊ถํ ๋ถ์ฌ
๐ ์ ์ฒด ๊ท์น ์์ฝํ
| ๊ท์น | ๋ด์ฉ | ์ด์ |
|---|---|---|
&T ์ฌ๋ฌ ๊ฐ | โ ๋์ OK | ์ฝ๊ธฐ๋ผ๋ฆฌ๋ ์์ |
&mut T 1๊ฐ๋ง | โ ๋์์ 2๊ฐ ๋ถ๊ฐ | ๋์ ์์ โ ์ถฉ๋ ๋ฐฉ์ง |
&T + &mut T | โ ๋์ ๋ถ๊ฐ | ์ฝ๋ ์ค ์์ โ ๋ฐ์ดํฐ ๊นจ์ง ๋ฐฉ์ง |
| NLL | ๋ง์ง๋ง ์ฌ์ฉ ์์ ๊ธฐ์ค | ๋ถํ์ํ ์ ์ฝ ์ํ |
| Dangling ๊ธ์ง | ์ฌ๋ผ์ง ๋ฐ์ดํฐ ์ฐธ์กฐ ๋ถ๊ฐ | ๋ฌดํจ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ๋ฐฉ์ง |
โ ๋ง์คํฐ ์ฒดํฌ๋ฆฌ์คํธ
- "ํ ๋ฒ์ ํ๋์ mutable reference๋ง" ๊ท์น์ ์ด์ ์ค๋ช
- "mutable๊ณผ immutable reference ๋์ ์ฌ์ฉ ๋ถ๊ฐ" ์ด์ ์ค๋ช
- Dangling reference๊ฐ ์ ์ํํ์ง, Rust๋ ์ด๋ป๊ฒ ๋ฐฉ์งํ๋์ง
- ์ปดํ์ผ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ณด๊ณ borrowing ๋ฌธ์ ํ์ ๊ฐ๋ฅ
- Reference๊ฐ ์ธ์ "drop"๋๋์ง ์ดํด (NLL)
๐ ์ฐธ๊ณ ์๋ฃ
๐ ๋ค์ ๋จ๊ณ
Day 9-10: Structs & Methods โ &self, &mut self ํจํด์ผ๋ก ์ค๋ ๋ฐฐ์ด borrowing์ ๊ตฌ์กฐ์ฒด์ ์ ์ฉ