μΌ | μ | ν | μ | λͺ© | κΈ | ν |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- C
- λ°μ΄ν°λ² μ΄μ€
- λ°±μ€ λ¬μ€νΈ
- λ¬μ€νΈ μμ
- μκ³ λ¦¬μ¦
- Operating System
- νμ΄μ¬
- Database
- Python challenge
- Reversing
- μλ°
- λ¬μ€νΈ
- data communication
- μλ° κΈ°μ΄
- μ°λΆν¬
- μ€λΌν΄DB
- java
- ubuntu
- νμ΄μ¬ μ²Όλ¦°μ§
- Rust
- μ΄μ체μ
- νμ΄μ¬ μκ³ λ¦¬μ¦
- νμ΄μ¬ μ±λ¦°μ§
- OS
- μ€λΌν΄
- μλ° κ°λ
- λ°μ΄ν° ν΅μ
- λ¬μ€νΈ νλ‘κ·Έλλ° κ³΅μ κ°μ΄λ
- λ°±μ€
- Python
Archives
- Today
- Total
IT’s Portfolio
[Rust] Start Rust (Day 22) - Functional Language Features: Iterators and Closures λ³Έλ¬Έ
Development Study/Rust
[Rust] Start Rust (Day 22) - Functional Language Features: Iterators and Closures
f1r3_r41n 2023. 11. 20. 14:58728x90
λ°μν
π¦ Rust Day 22
π³οΈ Functional Language Features: Iterators and Closures
- Closures : λ³μμ μ μ₯ν μ μλ ν¨μ νμμ ꡬ쑰
- Iterators : μΌλ ¨μ μμλ€μ μ²λ¦¬νλ λ°©λ²
1οΈβ£ ν΄λ‘μ : μ£Όλ³ νκ²½μ μΊ‘μ²νλ μ΅λͺ ν¨μ
- λ³μμ μ μ₯νκ±°λ λ€λ₯Έ ν¨μμ μΈμλ‘ μ λ¬νλ μ΅λͺ ν¨μ(anonymous functions)
- μΌλ° ν¨μμ λ¬λ¦¬ ν΄λ‘μ λ μμ μ΄ μ μλ λ²μ λ΄μ κ°λ€μ 'μΊ‘μ²(capture)'ν¨
π€ ν΄λ‘μ λ₯Ό μ΄μ©ν λμμ μΆμν
fn simulated_expensive_calculation(intensity: u32) -> u32 {
println!("μκ°μ΄ μ€λ 걸리λ κ³μ°μ μν μ€...");
thread::sleep(Duration::from_secs(2));
intensity
}
- μ€νμ 2μ΄κ° 걸리λ κ°μμ κ³μ°μ μννλ simulated_expensive_calculation ν¨μ
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(
simulated_user_specified_value,
simulated_random_number
);
}
- μ¬μ©μμ μ λ ₯κ³Ό μμμ μ«μλ₯Ό νλμ½λ©ν κ°μ μ΄μ©νλ main ν¨μ
fn generate_workout(intensity: u32, random_number: u32) {
if intensity < 25 {
println!(
"μ€λμ {}λ²μ νκ΅½νν΄κΈ°λ₯Ό νμΈμ!",
simulated_expensive_calculation(intensity)
);
println!(
"λ€μμλ {}λ²μ μλͺΈ μΌμΌν€κΈ°λ₯Ό νμΈμ!",
simulated_expensive_calculation(intensity)
);
} else {
if random_number == 3 {
println!("μ€λμ μλΆμ μΆ©λΆν μμ·¨νλ©° μ¬μΈμ!");
} else {
println!(
"μ€λμ {}λΆκ° λ¬λ¦¬κΈ°λ₯Ό νμΈμ!",
simulated_expensive_calculation(intensity)
);
}
}
}
- μ λ ₯κ°μ λ°λΌ simulated_expensive_calculation ν¨μλ₯Ό νΈμΆν΄μ μ΄λ κ³νμ μμ±νλ λ‘μ§
- simulated_expensive_calculation ν¨μλ₯Ό λ¨ ν λ²λ§ νΈμΆνλλ‘ λ¦¬ν©ν λ§ νμ
(1) ν¨μλ₯Ό μν 리ν©ν λ§
fn generate_workout(intensity: u32, random_number: u32) {
let expensive_result = simulated_expensive_calculation(intensity);
if intensity < 25 {
println!(
"μ€λμ {}λ²μ νκ΅½νν΄κΈ°λ₯Ό νμΈμ!",
expensive_result
);
println!(
"λ€μμλ {}λ²μ μλͺΈ μΌμΌν€κΈ°λ₯Ό νμΈμ!",
expensive_result
);
} else {
if random_number == 3 {
println!("μ€λμ μλΆμ μΆ©λΆν μμ·¨νλ©° μ¬μΈμ!");
} else {
println!(
"μ€λμ {}λΆκ° λ¬λ¦¬κΈ°λ₯Ό νμΈμ!",
expensive_result
);
}
}
}
- simulated_expensive_calculation ν¨μ νΈμΆμ ν λ²λ§ μννκ³ κ·Έ κ²°κ³Όλ₯Ό expensive_result λ³μμ μ μ₯
(2) μ½λλ₯Ό μ μ₯νλ ν΄λ‘μ λ₯Ό μ΄μ©ν 리ν©ν λ§
fn generate_workout(intensity: u32, random_number: u32) {
let expensive_closure = |num| {
println!("μκ°μ΄ μ€λ 걸리λ κ³μ°μ μν μ€...");
thread::sleep(Duration::from_secs(2));
num
};
if intensity < 25 {
println!(
"μ€λμ {}λ²μ νκ΅½νν΄κΈ°λ₯Ό νμΈμ!",
expensive_closure(intensity)
);
println!(
"λ€μμλ {}λ²μ μλͺΈ μΌμΌν€κΈ°λ₯Ό νμΈμ!",
expensive_closure(intensity)
);
} else {
if random_number == 3 {
println!("μ€λμ μλΆμ μΆ©λΆν μμ·¨νλ©° μ¬μΈμ!");
} else {
println!(
"μ€λμ {}λΆκ° λ¬λ¦¬κΈ°λ₯Ό νμΈμ!",
expensive_closure(intensity)
);
}
}
}
- ν΄λ‘μ λ₯Ό μ μΈνκ³ expensive_closure λ³μμ μ μ₯
- ν΄λ‘μ μ μΈμ λ³μμ κ°μ ν λΉνλ = λ€μλΆν° μμν¨
- ν΄λ‘μ μ μΈ μ νμ΄ν λ¬Έμμ μμ΄ νμν¨
- νμ΄ν λ¬Έμ μ¬μ΄μλ ν΄λ‘μ μ 맀κ°λ³μλ₯Ό μ§μ ν μ μμ
- ν΄λ‘μ λ₯Ό μ¬μ©νλ μ΄μ λ μ½λλ₯Ό ν κ³³μ μ μνκ³ κ·Έ μ½λλ₯Ό μ μ₯ν΄μ νμν λ λμ€μ νΈμΆνκΈ° μν¨
- expensive_closure ν΄λ‘μ λ₯Ό νΈμΆνλ generate_workout ν¨μ
π€ ν΄λ‘μ μ νμ μΆλ‘ κ³Ό μ λ Έν μ΄μ
let expensive_result = |num: u32| -> u32 {
println!("μκ°μ΄ μ€λ 걸리λ κ³μ°μ μν μ€...");
thread::sleep(Duration::from_secs(2));
num
}
- ν΄λ‘μ μ μΈ μ ν¨μμ²λΌ 맀κ°λ³μμ 리ν΄κ°μ νμ
μ μ§μ ν νμκ° μμ
- ν΄λ‘μ λ λ³μμ μ μ₯λκ³ μ΄λ¦λ μμΌλ©° λΌμ΄λΈλ¬λ¦¬μ μ¬μ©μμκ² λ ΈμΆλμ§λ μμ
- λ³μμ λ§μ°¬κ°μ§λ‘ κ°λ μ±μ λμ΄λ μΌμ΄ μ₯ν©ν μ½λλ₯Ό μμ±νλ κ²λ³΄λ€ λ μ€μν λ ν΄λ‘μ μλ νμ μ λ Έν μ΄μ μ μΆκ°ν μ μμ
fn add_one_1(x: u32) -> u32 { x+1 } // ν¨μμ μ μ
let add_one_2 = |x: u32| -> u32 { x+1 }; // νμ
μ λ
Έν
μ΄μ
μ μ μ©ν ν΄λ‘μ μ μΈ
let add_one_3 = |x| { x+1 }; // ν΄λ‘μ μ μΈμμ νμ
μ λ
Έν
μ΄μ
μ κ±°
let add_one_4 = |x| x+1; // νλμ ννμμΌλ‘λ§ κ΅¬νλ ν΄λ‘μ μ μΈμ΄λ―λ‘ κ΄νΈκΉμ§ μ κ±°ν¨
let example_closure = |x| x
let s = example_closure(String::from("hello"));
let n = example_closure(5);
- μ²μ String νμ
μ μΈμλ‘ λ£μ΄ νΈμΆν ν΄λ‘μ λ λ€λ₯Έ νμ
μ μΈμλ‘ λ£μ΄ νΈμΆνλ©΄ μλ¬κ° λ°μν¨
- μ²μ νμ μ λ³΄κ° ν΄λΉ ν΄λ‘μ μ κΈ°λ‘λκΈ° λλ¬Έ
π€ μ λ€λ¦ 맀κ°λ³μμ Fn νΈλ μ΄νΈλ₯Ό μ΄μ©ν΄ ν΄λ‘μ μ μ₯νκΈ°
λ©λͺ¨μ΄μ μ΄μ (memoization) or μ§μ° νκ°(lazy evaluation)
κΈ°λ²- ν΄λ‘μ μ ν΄λ‘μ μ μ€ν κ²°κ³Όλ₯Ό μ μ₯ν ꡬ쑰체 μ μΈ
- ꡬ쑰체λ κ²°κ΄κ°μ΄ νμν λλ§ ν΄λ‘μ λ₯Ό μ€νν ν κ·Έ κ²°κ΄κ°μ μΊμ±ν¨
- λλ¨Έμ§ μ½λμμλ κ·Έ κ²°κ΄κ°μ λ°λ‘ μ μ₯νκ³ μ¬μ¬μ©νλ μ½λλ₯Ό μμ±νμ§ μμλ λ¨
struct Cacher<T> where T: Fn(u32) -> u32 {
calculation: T,
value: Option<u32>,
}
- ν΄λ‘μ μ 리ν΄κ°μ calculationκ³Ό value νλμ μ μ₯νλ Cacher ꡬ쑰체
- ꡬ쑰체 μ μΈ μ κ° νλμ νμ μ μμμΌ νλ―λ‘ ν΄λ‘μ μ νμ μ λͺ μν΄μΌ ν¨
- ν΄λ‘μ μΈμ€ν΄μ€λ κ°μ μ μΌν μ΅λͺ
νμ
μ κ°μ§κ³ μμ
- λ κ°μ ν΄λ‘μ κ° κ°μ μκ·Έλμ²λ₯Ό κ°λλΌλ μλ‘ λ€λ₯Έ νμ μΌλ‘ μΈμν¨
- μ λ€λ¦ T νμ
μ calculation νλ
- T νμ μ Fn νΈλ μ΄νΈ κ²½κ³λ₯Ό μ§μ ν΄ μ΄ νμ μ΄ ν΄λ‘μ μ¬μΌ νλλ μ¬μ€μ λͺ μν¨
- Option
νμ μ value νλ - ν΄λ‘μ λ₯Ό μ€ννκΈ° μ μλ None κ°μ
- ꡬ쑰체λ₯Ό μ΄μ©νλ μ½λκ° ν΄λ‘μ μ κ²°κ³Όλ₯Ό μμ²νλ©΄ κ·Έ μμ μ ν΄λ‘μ λ₯Ό νΈμΆν λ€ κ²°κ΄κ°μ Some μ΄κ²κ°μ μ μ₯ν΄ νλμ μ μ₯
impl<T> Cacher<T> where T: Fn(u32) -> u32 {
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: None,
}
}
fn value(&mut self, arg: u32) -> u32 {
match self.value {
Some(v) => v,
None => {
let v = (self.calculation)(arg);
self.value = Some(v);
v
}
}
}
}
- Cacher ꡬ쑰체μ μΊμ± λ‘μ§
- λ€λ₯Έ μ½λκ° κ΅¬μ‘°μ²΄μ value νλκ°μ μμλ‘ λ³κ²½νκΈ°λ₯Ό μμΉ μκΈ° λλ¬Έμ μ΄ νλλ λΉκ³΅κ°λ‘ μ μΈν¨
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_result = Cacher::new(
|num| {
println!("μκ°μ΄ μ€λ 걸리λ κ³μ°μ μν μ€...");
thread::sleep(Duration::from_secs(2));
num
}
);
if intensity < 25 {
println!(
"μ€λμ {}λ²μ νκ΅½νν΄κΈ°λ₯Ό νμΈμ!",
expensive_result.value(intensity)
);
println!(
"λ€μμλ {}λ²μ μλͺΈ μΌμΌν€κΈ°λ₯Ό νμΈμ!",
expensive_result.value(intensity)
);
} else {
if random_number == 3 {
println!("μ€λμ μλΆμ μΆ©λΆν μμ·¨νλ©° μ¬μΈμ!");
} else {
println!(
"μ€λμ {}λΆκ° λ¬λ¦¬κΈ°λ₯Ό νμΈμ!",
expensive_result.value(intensity)
);
}
}
}
- generate_workout ν¨μμμ Cacher ꡬ쑰체λ₯Ό μ΄μ©ν΄ μΊμ± λ‘μ§ μΆμν
π€ Cacher ꡬνμ νκ³
- κ° μΊμ± λ°©λ²μ λ€λ₯Έ μ½λμμ λ€λ₯Έ ν΄λ‘μ λ₯Ό νΈμΆν λ μ μ©ν¨
- Cacher ꡬ쑰체μ λ¬Έμ
- Cacher μΈμ€ν΄μ€λ νμ μ²μμΌλ‘ νΈμΆλ value λ©μλμ 맀κ°λ³μ argμ μ λ¬λ κ°κ³Ό κ°λ€λ μ
- Cacherκ° νλμ κ° λμ ν΄μ 맡μ μ μ₯νλλ‘ μμ ν΄μΌ ν¨
- u32 νμ
μ 맀κ°λ³μ νλμ u32 νμ
μ 리ν΄κ°μ κ°μ§λ ν΄λ‘μ λ§ μ μ₯ν μ μλ€λ μ
- λ¬Έμμ΄ μ¬λΌμ΄μ€λ₯Ό μΈμλ‘ μ λ¬λ°μ usize κ°μ 리ν΄νλ ν΄λ‘μ μ μ€ν κ²°κ³Όλ μΊμν μ μμ
- μ λ€λ¦ 맀κ°λ³μλ₯Ό μ¬μ©ν΄μΌ ν¨
- Cacher μΈμ€ν΄μ€λ νμ μ²μμΌλ‘ νΈμΆλ value λ©μλμ 맀κ°λ³μ argμ μ λ¬λ κ°κ³Ό κ°λ€λ μ
#[test]
fn call_with_different_value() {
let mut c = Cacher::new(|a| a);
let v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 2);
}
- μ²μ c.value λ©μλμ 1μ μ λ¬ν΄ νΈμΆνλ©΄ Cacher μΈμ€ν΄μ€κ° self.value νλμ Some(1) κ°μ μ μ₯ν¨
- μ΄ν value λ©μλμ μ΄λ€ κ°μ μ λ¬νλ 무쑰건 1μ 리ν΄ν¨
- ν΄λΉ ν μ€νΈλ μ€ν¨ν¨
π€ ν΄λ‘μ λ₯Ό μ΄μ©ν΄ μ£Όλ³ νκ²½ μΊ‘μ²νκΈ°
fn main() {
let x = 4;
let equal_to_x = |z| z == x;
let y = 4;
assert!(equal_to_x(y));
}
- μμ μ£Όλ³μ μ μΈλ λ³μλ₯Ό μ°Έμ‘°νλ ν΄λ‘μ
- λ³μ xλ equal_to_x ν΄λ‘μ μ 맀κ°λ³μκ° μλλ°λ μμ μ΄ μ μΈλ κ²κ³Ό κ°μ λ²μμ μ μΈλ λ³μ xμ μ κ·Όν μ μμ
fn main() {
let x = 4;
fn equal_to_x(z: i32) -> bool { z == x };
let y = 4;
assert!(equal_to_x(y));
}
- ν΄λ‘μ λ₯Ό ν¨μλ‘ λ°κΎΌ μ½λ
- μ»΄νμΌλμ§ μμ
- ν΄λ‘μ λ μμ μ μ£Όλ³μμ κ°μ μΊ‘μ²ν λ ν΄λ‘μ μ λ³Έλ¬Έμμ μ¬μ©ν κ°μ λ©λͺ¨λ¦¬μ μ μ₯ν¨
- λ©λͺ¨λ¦¬λ₯Ό μ΄λ κ² μ¬μ©νλ©΄ μ£Όλ³μ κ°μ μΊ‘μ²ν νμκ° μλ μ½λλ₯Ό μ€νν λ보λ€λ λ λ§μ μ€λ²ν€λκ° λ°μν¨
- ν¨μλ μ£Όλ³μ νκ²½μ μΊ‘μ²νμ§ μμ
- μ£Όλ³μ κ°μ΄ νμνμ§ μμ λλ μ€λ²ν€λλ₯Ό μ€μ΄κΈ° μν΄ ν¨μλ₯Ό μ¬μ©
- ν΄λ‘μ λ μμ μ μ£Όλ³μ μ μΈλ κ°μ ν¨μκ° λ§€κ°λ³μλ₯Ό μ μ₯νλ μΈ κ°μ§ λ°©λ²κ³Ό λμΌνκ² μΊ‘μ²ν¨
- μμ κΆμ κ°μ Έμ€λ λ°©λ²
- FnOnce νΈλ μ΄νΈλ κ°μ λ²μμ μ μΈλ λ³μλ₯Ό μ¬μ©ν μ μμ
- μ΄ λ²μλ₯Ό ν΄λ‘μ μ 'νκ²½(environment)'μ΄λΌκ³ ν¨
- ν΄λ‘μ λ μΊ‘μ²λ λ³μλ₯Ό μ¬μ©νλ €λ©΄ λ°λμ μ΄ λ³μλ€μ μμ κΆμ κ°μ ΈμΌ νλ©°, ν΄λ‘μ λ₯Ό μ μΈνλ μμ μ μ΄ λ³μλ₯Ό ν΄λ‘μ μμΌλ‘ μ΄λν¨
- νΈλ μ΄νΈμ μ΄λ¦μμ Onceκ° μλ―Ένλ κ²μ ν΄λ‘μ κ° κ°μ κ°μ λν μμ κΆμ μ€μ§ ν λ²λ§ κ°μ§λ€λ λ»μ
- FnOnce νΈλ μ΄νΈλ κ°μ λ²μμ μ μΈλ λ³μλ₯Ό μ¬μ©ν μ μμ
- κ°μ κ°λ³μΌλ‘ λμ¬νλ λ°©λ²
- FnMut νΈλ μ΄νΈλ κ°μ κ°λ³μΌλ‘ λμ¬νλ―λ‘ νκ²½μμ κ°μ Έμ¨ κ°μ λ³κ²½ν μ μμ
- κ°μ λΆλ³μΌλ‘ λμ¬νλ λ°©λ²
- Fn νΈλ μ΄νΈλ νκ²½μμ κ°μ λΆλ³μΌλ‘ λμ¬ν¨
- μμ κΆμ κ°μ Έμ€λ λ°©λ²
- λͺ¨λ ν΄λ‘μ λ μ΅μν ν λ²μ νΈμΆλ μ μμΌλ―λ‘ FnOnce νΈλ μ΄νΈλ₯Ό ꡬνν¨
- νκ²½μμ κ°μ Έμ¨ κ°μ μ΄λνμ§ μλ ν΄λ‘μ λ FnMut νΈλ μ΄νΈλ ꡬννκ² λλ©° μΊ‘μ²λ λ³μλ₯Ό λ³κ²½νμ§ μλ ν΄λ‘μ λ Fn νΈλ μ΄νΈλ₯Ό ꡬνν¨
- ν΄λ‘μ κ° νκ²½μμ κ°μ Έμ¨ κ°μ λν μμ κΆμ κ°κ² νλ €λ©΄ 맀κ°λ³μ λͺ©λ‘ μμ move ν€μλλ₯Ό μ§μ ν¨
- μ΄ κΈ°λ²μ ν΄λ‘μ λ₯Ό μλ‘μ΄ μ€λ λμ μ λ¬ν΄μ κ·Έ μ€λ λμ λ°μ΄ν°λ₯Ό μ΄λν΄μ μμ νκ² ν λ μ μ©ν¨
fn main() {
let x = vec![1, 2, 3];
let equal_to_x = move |z| z == x;
println!("λ³μ xλ₯Ό μ¬μ©ν μ μμ΅λλ€: {:?}", x);
let y = vec![1, 2, 3];
assert!(equal_to_x(y));
}
- μ΄ μ½λλ μλ¬κ° λ°μν¨
- ν΄λ‘μ μ μΈ μ λ³μ xλ move ν€μλλ‘ μΈν΄ ν΄λ‘μ μμΌλ‘ μ΄λν¨
- ν΄λ‘μ κ° xμ μμ κΆμ κ°μ§λ―λ‘ main ν¨μλ println! 맀ν¬λ‘λ₯Ό νΈμΆν λ xμ μ κ·Όν μ μμ
2οΈβ£ λ°λ³΅μλ₯Ό μ΄μ©ν΄ μΌλ ¨μ μμ΄ν μ²λ¦¬νκΈ°
- λ°λ³΅μλ μμ΄ν μ μννλ©΄μ λ§μ§λ§ μμ΄ν μ λλ¬νλ λλ₯Ό νλ¨ν¨
- μ§μ°(lazy) νΉμ±μ΄ μμ
- λ°λ³΅μλ₯Ό λ³μμ μ μ₯ν λλ μμ΄ν μ μννλ μμ μ΄ μ§νλμ§ μμ
- for 루νκ° λ³μλ₯Ό νΈμΆνλ©΄ λ°λ³΅μλ₯Ό μ΄μ©ν΄ κ° μμ΄ν μ μννκ³ κ°λ³ κ°μ μΆλ ₯ν¨
- λ¬μ€νΈμμλ λ°λ³΅μλ‘ λ°λ³΅λλ λ‘μ§μ μ€μΌ μ μμΌλ©° μ μ°μ±κΉμ§ κ°μ§ μ μμ
π€ Iterator νΈλ μ΄νΈμ next λ©μλ
- λͺ¨λ λ°λ³΅μλ€μ νμ€ λΌμ΄λΈλ¬λ¦¬μ μ μλ Iterator νΈλ μ΄νΈλ₯Ό ꡬνν¨
pub trait Iterator {
type Item,
fn next(&mut self) -> Option<Self::Item>;
}
- Iterator νΈλ μ΄νΈλ₯Ό ꡬννλ €λ©΄ Item νμ λ μ μν΄μΌ νλ©°, μ΄ Item νμ μ next λ©μλμ λ¦¬ν΄ νμ μΌλ‘ μ¬μ©ν¨
#[test]
fn iterator_demonstration() {
let v1 = vec![1, 2, 3];
let mut v1_iter = v1.iter();
assert_eq!(v1_iter.next(), Some(&1));
assert_eq!(v1_iter.next(), Some(&2));
assert_eq!(v1_iter.next(), Some(&3));
assert_eq!(v1_iter.next(), None);
}
- λ°λ³΅μμ next λ©μλ νΈμΆ
- v1_iter λ³μλ₯Ό κ°λ³μΌλ‘ μ μΈν¨
- next λ©μλλ‘ νΈμΆνλ©΄ μ΄λ―Έ 리ν΄ν κ°μ μΆμ νλ €κ³ λ°λ³΅μ λ΄λΆμ μνκ° λ³κ²½λ¨
- λ°λ³΅μλ₯Ό 'μλΉ(consume)' ν¨
- next λ©μλ νΈμΆ λλ§λ€ λ°λ³΅μμ μμ΄ν μ 리ν΄ν¨
- v1_iter λ³μλ₯Ό for 루ν μμμ μ¬μ©νλ©΄ 루νκ° v1_iterμ λν μμ κΆμ κ°μ§κ³ κ°λ³ λ³μλ‘ λ§λ€κΈ° λλ¬Έμ λ°λ³΅μ λ³μλ₯Ό κ°λ³ λ³μλ‘ μ μΈν νμκ° μμ
- next λ©μλλ‘ μ»μ΄μ¨ κ°μ λ²‘ν° μμ μ μ₯λ κ°μ λν λΆλ³ μ°Έμ‘°μ
- iter λ©μλλ λΆλ³ μ°Έμ‘°λ₯Ό μννλ λ°λ³΅μλ₯Ό μμ±ν¨
- v1μ λν μμ κΆμ κ°μ§κ³ μμ ν κ°μ 리ν΄νλ λ°λ³΅μ μμ± μ iter λμ into_iter λ©μλ νΈμΆ
- κ°λ³ μ°Έμ‘° μν μ iter λμ iter_mut λ©μλ νΈμΆ
π€ λ°λ³΅μλ₯Ό μλΉνλ λ©μλ
- μΌλΆ λ©μλλ next λ©μλλ₯Ό νΈμΆνλ―λ‘ Iterator νΈλ μ΄νΈλ₯Ό ꡬννλ €λ©΄ next λ©μλλ₯Ό λ°λμ ꡬνν΄μΌ ν¨
- μλΉ μ΄λν°(consuming adaptors)
- λ΄λΆμ μΌλ‘ λ°λ³΅μλ₯Ό μλΉνλ next λ©μλλ₯Ό νΈμΆνλ λ©μλ
#[test]
fn iterator_sum() {
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
let total: i32 = v1_iter.sum();
assert_eq!(total, 6);
}
- λ°λ³΅μ λ΄ μμ΄ν μ΄ν©μ μ»κΈ° μν΄ sum λ©μλ νΈμΆ
- sum λ©μλλ λ°λ³΅μμ λν μμ κΆμ κ°κΈ° λλ¬Έμ μ΄ λ©μλλ₯Ό νΈμΆν νμλ v1_iter λ³μλ₯Ό λ μ΄μ μ¬μ©ν μ μμ
π€ λ€λ₯Έ λ°λ³΅μλ₯Ό μμ±νλ λ©μλ
- λ°λ³΅μ μ΄λν°(iterator adaptors)
- λ°λ³΅μλ₯Ό λ€λ₯Έ μ’ λ₯μ λ°λ³΅μλ‘ λ³κ²½ν¨
- λͺ¨λ λ°λ³΅μλ μ§μ° νΉμ±μ΄ μμΌλ―λ‘ λ°λ³΅μ μ΄λν°λ₯Ό νΈμΆν νμ κ²°κ³Όλ₯Ό μ»μΌλ €λ©΄ μλΉ μ΄λν° λ©μλ μ€ νλλ₯Ό νΈμΆν΄μΌ ν¨
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
v1.iter().map(|x| x+1);
}
- μλ‘μ΄ λ°λ³΅μλ₯Ό μμ±νλ λ°λ³΅μ μ΄λν° map λ©μλ
- ν΄λΉ μ½λλ μλ¬΄λ° μμ
λ μννμ§ μμ
- map λ©μλμ μ λ¬ν ν΄λ‘μ λ μ λ νΈμΆλμ§ μμ
fn main() {
let v1: Vec<i32> = vec![1, 2, 3];
let v2 = v1.iter().map(|x| x+1).collect::<Vec<_>>();
assert_eq!(v2, vec![2, 3, 4]);
}
- map λ©μλλ‘ μλ‘μ΄ λ°λ³΅μ μμ± ν collect λ©μλλ‘ λ²‘ν° μμ±
- map λ©μλλ ν΄λ‘μ λ₯Ό 맀κ°λ³μλ‘ μ¬μ©νλ―λ‘ κ° μμ΄ν μ μ μ©ν μ΄λ€ μμ λ μ λ¬ κ°λ₯
π€ νκ²½μ μΊ‘μ²νλ ν΄λ‘μ μ νμ©
- λ°λ³΅μμ filter λ©μλλ λ°λ³΅μλ‘λΆν° κ° μμ΄ν μ κ°μ Έμ λΆλ¦¬μΈκ°μ 리ν΄νλ ν΄λ‘μ μ μ λ¬ν¨
- ν΄λ‘μ κ° trueλ₯Ό 리ν΄νλ©΄ κ·Έ κ°μ filter λ©μλκ° μμ±νλ λ°λ³΅μμ μΆκ°λκ³ falseλ₯Ό 리ν΄νλ©΄ μΆκ°λμ§ μμ
#[derive(PartialEq, Debug)]
struct Shoe {
size: u32,
style: String,
}
fn shoe_in_my_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
shoes.into_iter()
.filter(|s| s.size == shoe_size)
.collect()
}
#[test]
fn filters_by_size() {
let shoes = vec![
Shoe { size: 10, style: String::from("μ€λ컀μ¦") },
Shoe { size: 13, style: String::from("μλ¬") },
Shoe { size: 10, style: String::from("λΆμΈ ") },
];
let in_my_size = shoe_in_my_size(shoes, 10);
assert_eq!(
in_my_size,
vec![
Shoe { size: 10, style: String::from("μ€λ컀μ¦") },
Shoe { size: 10, style: String::from("λΆμΈ ") },
]
);
}
- shoe_size λ³μλ₯Ό μΊ‘μ²ν ν΄λ‘μ λ₯Ό filter λ©μλμ μ λ¬
π€ Iterator νΈλ μ΄νΈλ₯Ό μ΄μ©ν΄ μ§μ λ°λ³΅μ ꡬννκΈ°
- μ§μ μ μΈν νμ
μ Iterator νΈλ μ΄νΈλ₯Ό ꡬνν΄μ νμν μμ
μν κ°λ₯
- next λ©μλ ꡬν μ Iterator νΈλ μ΄νΈκ° κΈ°λ³Έμ μΌλ‘ ꡬνν΄ μ 곡νλ λ€λ₯Έ λ©μλλ λͺ¨λ μ¬μ© κ°λ₯
struct Counter {
count: u32,
}
impl Counter {
fn new() -> Counter {
Counter { count: 0 }
}
}
- Counter ꡬ쑰체λ₯Ό μ μΈνκ³ count νλμ 0μ μ΄κΉκ°μΌλ‘ λμ ν΄ μ μΈμ€ν΄μ€λ₯Ό μμ±νλ new ν¨μ
impl Iterator for Counter {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
self.count += 1;
if self.count < 6 {
Some(self.count)
} else {
None
}
}
}
- Counter ꡬ쑰체μ Iterator νΈλ μ΄νΈ ꡬν
- λ°λ³΅μκ° u32 κ°μ 리ν΄νλλ‘ λ°λ³΅μμ μ°κ΄λ νμ μΈ Item νμ μ u32λ‘ μ§μ
- 0μΌλ‘ μ΄κΈ°ννλ νμ¬ μνμ 1μ λν΄μ λ°λ³΅μκ° 1λΆν° 리ν΄νλλ‘ ν¨
- λ§μΌ, count κ°μ΄ 6λ³΄λ€ μμΌλ©΄ next λ©μλλ νμ¬ κ°μ Some κ°μ μ μ₯ν΄ λ¦¬ν΄νκ³ , count κ°μ΄ 6λ³΄λ€ ν¬λ©΄ None κ°μ 리ν΄ν¨
π€ Counter λ°λ³΅μμ next λ©μλ μ¬μ©νκΈ°
#[test]
fn calling_next_directly() {
let mut counter = Counter::new();
assert_eq!(counter.next(), Some(1));
assert_eq!(counter.next(), Some(2));
assert_eq!(counter.next(), Some(3));
assert_eq!(counter.next(), Some(4));
assert_eq!(counter.next(), Some(5));
assert_eq!(counter.next(), None);
}
- next λ©μλ ꡬν ν μ€νΈ
π€ Iterator νΈλ μ΄νΈμ λ€λ₯Έ λ©μλ νμ©νκΈ°
#[test]
fn using_other_iterator_trait_methods() {
let sum: u32 = Counter::new().zip(Counter::new().skip(1))
.map(|(a, b)| a*b)
.filter(|x| x%3==0)
.sum();
assert_eq!(18, sum);
}
- Counter ꡬ쑰체μ μΈμ€ν΄μ€κ° μμ±ν κ°μ λ€λ₯Έ Counter μΈμ€ν΄μ€κ° μμ±ν κ° μ€ μ²« λ²μ§Έ κ°μ μ μΈν λλ¨Έμ§μ μ§μ§μ΄ μλ‘λ₯Ό κ³±ν ν, 3μΌλ‘ λλμ΄ λ¨μ΄μ§λ κ°λ§ κ³¨λΌ κ²°κ΄κ°μ λͺ¨λ λν¨
- zip λ©μλλ λ€ κ°μ μλ§ μμ±
- λ λ°λ³΅μ μ€ μ΄λ νλκ° None κ°μ 리ν΄νλ©΄ Noneμ 리ν΄νλ―λ‘ λ€μ― λ²μ§Έ μ§μΈ (5, None)μ μμ±λμ§ μμ
- zip λ©μλλ λ€ κ°μ μλ§ μμ±
- next λ©μλ λμμ ꡬννμΌλ―λ‘ λλ¨Έμ§ λͺ¨λ λ©μλλ νΈμΆν μ μμμ νμΈ κ°λ₯
3οΈβ£ μ μΆλ ₯ νλ‘μ νΈμ κ°μ
π€ λ°λ³΅μλ₯Ό μ΄μ©ν΄ clone λ©μλ νΈμΆ μ κ±°νκΈ°
impl Config {
pub fn new(args: &[String]) -> Result<Config, &'static str> {
if args.len() < 3 {
return Err("νμν μΈμκ° μ§μ λμ§ μμμ΅λλ€.");
}
Ok(Config {
query: args[1].clone(),
filename: args[2].clone(),
case_sensitive: env::var("CASE_INSENSITIVE").is_err()
})
}
}
- Config::new ν¨μμ λΉν¨μ¨μ μΈ clone λ©μλ
- new ν¨μκ° String μ¬λΌμ΄μ€μΈ args λ³μλ₯Ό μμ νμ§ μμκΈ°μ clone λ©μλλ₯Ό μ¬μ©νμ
- μ΄μ new ν¨μκ° μ¬λΌμ΄μ€λ₯Ό λμ¬νλ λμ μΈμλ‘ μ λ¬λ λ°λ³΅μμ μμ κΆμ κ°λλ‘ μμ νλ©΄ λ¨
- Config::new ν¨μκ° λ°λ³΅μμ μμ κΆμ ν보νκ³ κ°μ λμ¬νλ μΈλ±μ€ μμ μ μ κ±°νλ©΄ clone λ©μλλ₯Ό μ¬μ©ν΄ μλ‘μ΄ λ©λͺ¨λ¦¬ ν λΉμ μννλ λμ λ°λ³΅μλ‘λΆν° String κ°μ Config μΈμ€ν΄μ€λ‘ μ΄λν μ μμ
π€ 리ν΄λ λ°λ³΅μλ₯Ό μ§μ μ¬μ©νλ λ°©λ²
use std::{env, process};
use minigrep::Config;
fn main() {
let config = Config::new(env::args()).unwrap_or_else(|err| {
eprintln!("μΈμλ₯Ό ꡬ문λΆμνλ λμ μ€λ₯κ° λ°μνμ΅λλ€: {}", err);
process::exit(1);
});
println!("κ²μμ΄: {}\nνμΌ μ΄λ¦: {}", config.query, config.filename);
if let Err(e) = minigrep::run(config) {
eprintln!("μ ν리μΌμ΄μ
μλ¬: {}", e);
process::exit(1);
}
}
- env::args ν¨μμ 리ν΄κ°μ Config::new ν¨μμ κ·Έλλ‘ μ λ¬
impl Config {
pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
- λ°λ³΅μλ₯Ό μ¬μ©νλλ‘ μμ ν Config::new ν¨μμ μκ·Έλμ²
- env::args ν¨μλ std::env::Args νμ
μ λ°λ³΅μλ₯Ό 리ν΄ν¨
- ν΄λΉ λ°λ³΅μλ₯Ό μνν΄μΌ νλ―λ‘ κ°λ³ 맀κ°λ³μλ‘ μ μΈν¨
π€ μΈλ±μ€ λμ Iterator νΈλ μ΄νΈμ λ©μλ νμ©νκΈ°
impl Config {
pub fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
args.next();
Ok(Config {
query: {
match args.next() {
Some(arg) => arg,
None => return Err("κ²μμ΄λ₯Ό μ§μ ν΄μΌ ν©λλ€."),
}
},
filename: {
match args.next() {
Some(arg) => arg,
None => return Err("νμΌλͺ
μ μ§μ ν΄μΌ ν©λλ€."),
}
},
case_sensitive: {
env::var("CASE_INSENSITIVE").is_err()
},
})
}
}
- λ°λ³΅μ λ©μλλ₯Ό μ¬μ©νλλ‘ μμ ν Config::new ν¨μ
- env::args ν¨μκ° λ¦¬ν΄νλ κ°μ 첫 λ²μ§Έλ νλ‘κ·Έλ¨μ μ΄λ¦
- μ΄ κ°μ 무μ
π€ λ°λ³΅μ μ΄λν°λ₯Ό μ΄μ©ν΄ λ κΉλν μ½λ μμ±νκΈ°
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
let mut v = vec![];
for l in contents.lines() {
if l.contains(query) {
v.push(l);
}
}
v
}
- κΈ°μ‘΄μ search ν¨μ
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents.lines()
.filter(|l| l.contains(query))
.collect()
}
- λ°λ³΅μ μ΄λν°λ₯Ό μ΄μ©ν΄ λ€μ ꡬνν search ν¨μ
- ν¨μν νλ‘κ·Έλλ°μ κ°λ³ μνμ μμ μ΅μνν΄μ μ½λλ₯Ό λ κΉλνκ² μ μ§νλ λ° λμμ΄ λ¨
- κ°λ³ μνλ₯Ό μ κ±°νλ©΄ μ€κ°κ°μ μ μ₯ν 벑ν°λ₯Ό μ¬μ©ν νμκ° μμ΄μ Έμ λμ€μ κ²μμ λ³λ ¬ μ€νμ μ§μνκΈ°λ μ 리ν¨
pub fn search_case_insensitive<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
contents.lines()
.filter(|l| l.to_lowercase().contains(&query.to_lowercase()))
.collect()
}
- κ°μ λ°©μμΌλ‘ λ€μ ꡬνν search_case_insensitive ν¨μ
π€ 루νμ λ°λ³΅μμ μ±λ₯ λΉκ΅
- λ°λ³΅μκ° κ³ μμ€μ μΆμνλ₯Ό μ 곡νκΈ°λ νμ§λ§ μ§μ μμ±νλ μ μμ€μ μ½λμ κ±°μ κ°μ μ½λλ‘ μ»΄νμΌλ¨
- λ°λ³΅μλ λ¬μ€νΈμ 무λΉμ© μΆμν(zero-cost abstractions) κΈ°λ₯ μ€ νλμ
- μΆμνλ₯Ό μ¬μ©νλ€κ³ μΆκ°μ μΈ λ°νμ μ€λ²ν€λκ° λ°μνμ§ μμ
fn main() {
let buf: &mut [i32];
let coefficients: [i64; 12];
let qlp_shift: i16;
for i in 12..buf.len() {
let prediction = coefficients.iter()
.zip(&buf[i-12..i])
.map(|(&c, &s)| c*s as i64)
.sum::<i64>() >> qlp_shift;
let delta = buf[i];
buf[i] = prediction as i32 + delta;
}
}
- prediction κ°μ κ³μ°νκΈ° μν΄ coefficients λ°°μ΄μ 12κ° κ°μ μννλ©΄μ zip λ©μλλ₯Ό μ΄μ©ν΄ bufμ μ μ₯λ μ΄μ 12κ° κ°μ μ΄μ©ν΄ κ°μ μμ λ§λ¬
- κ° μμ κ°λ€μ κ³±νκ³ κ·Έ κ²°κ³Όλ₯Ό λͺ¨λ λν΄μ qlp_shift λ³μμ μ§μ λ λΉνΈλ§νΌ μ€λ₯Έμͺ½μΌλ‘ μ΄λν¨
- ν΄λΉ μ½λλ κ°λ°μκ° μμΌλ‘ μμ±νλ κ²κ³Ό κ°μ μ΄μ
λΈλ¦¬ μ½λλ‘ μ»΄νμΌλ¨
- coefficients λ°°μ΄μ κ°μ μννλ λ° νμν 루νλ μ‘΄μ¬νμ§ μμ§λ§ λ¬μ€νΈλ 12κ°μ μμ΄ν μ μνν΄μΌ νλ€λ κ²μ μκ³ μμΌλ―λ‘ λ£¨νλ₯Ό νμ΄λ
- μ¬κΈ°μ νμ΄λΈλ€λ κ²μ 루νλ₯Ό μ μ΄νλ μ½λμ μ€λ²ν€λλ₯Ό μμ κΈ° μν΄ λ£¨νλ₯Ό μ κ±°νκ³ λ£¨ν μμμ μ€νλλ μ½λλ₯Ό νμν νμλ§νΌ λ°λ³΅νλ μ½λλ₯Ό μμ±νλ κ³Όμ μ λ»ν¨
- coefficients λ°°μ΄μ λͺ¨λ κ°λ€μ λ μ§μ€ν°μ μ μ₯λ¨
- κ°μ λ§€μ° λΉ λ₯΄κ² μ κ·Ό κ°λ₯
- λ°°μ΄ μ κ·Ό μ λ°νμμ κ²½κ³κ° κ²μ¬λ μ€ννμ§ μμ
Summary
- ν΄λ‘μ μ λ°λ³΅μλ ν¨μν νλ‘κ·Έλλ° μΈμ΄λ‘λΆν° μ°¨μ©ν κΈ°λ₯
- ν΄λ‘μ μ λ°λ³΅μμ ꡬνμ λ°νμ μ±λ₯μ κ±°μ μν₯μ λ―ΈμΉμ§ μμ
- 무λΉμ© μΆμνλ₯Ό λ¬μ±νκΈ° μν λ Έλ ₯μ μΌν
728x90
λ°μν
'Development Study > Rust' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Rust] Start Rust (Day 23) - More About Cargo and Crates.io (1) | 2023.11.25 |
---|---|
[System] The Elements of Computing System - 4 (0) | 2023.11.08 |
[System] The Elements of Computing System - 3 (1) | 2023.11.08 |
[System] The Elements of Computing System - 2 (1) | 2023.11.04 |
[System] The Elements of Computing System - 1 (1) | 2023.10.31 |
Comments