홈강좌Rust 입문·중급 47편 중 14편째
Rust for 와 범위 — 배열과 0..n 을 처음부터 끝까지 돈다
Rust 의 for 는 배열이나 범위의 값을 하나씩 꺼내 되풀이한다. 0..3 은 0·1·2, 1..=3 은 1·2·3 이고, .rev() 를 붙이면 거꾸로 돈다. 번호를 직접 세지 않으니 범위를 벗어날 일이 없어서, 정해진 만큼 돌 때는 for 가 기본이다.
01 배열을 처음부터 끝까지
9편의 점수 배열을 하나씩 찍어 보자.
fn main() {
let scores = [72, 85, 90];
for score in scores {
println!("{score}");
}
} Compiling scores v0.1.0 (~/projects/scores)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/scores`
72
85
90for score in scores 는 "scores 의 값을 하나씩 꺼내 score 에 담고 중괄호 안을 실행하라" 는 뜻이다. 값을 다 꺼내면 저절로 끝난다. 번호 변수도, 끝 조건도, break 도 필요 없다.
13편의 while 로 scores[i] 를 돌면 i 를 늘리는 줄을 빠뜨리거나 끝 번호를 잘못 써서 9편의 범위 밖 패닉을 낼 수 있다. for 는 그럴 일이 없다.
02 범위 — 0..n 과 1..=n
숫자를 차례로 돌 때는 범위를 쓴다.
fn main() {
for i in 0..3 {
println!("0..3 -> {i}");
}
for i in 1..=3 {
println!("1..=3 -> {i}");
}
for i in (1..=3).rev() {
println!("rev -> {i}");
}
} Compiling ranges v0.1.0 (~/projects/ranges)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.19s
Running `target/debug/ranges`
0..3 -> 0
0..3 -> 1
0..3 -> 2
1..=3 -> 1
1..=3 -> 2
1..=3 -> 3
rev -> 3
rev -> 2
rev -> 1| 범위 | 뜻 | 값 |
|---|---|---|
0..3 | 0 부터 3 바로 앞까지 | 0, 1, 2 |
1..=3 | 1 부터 3 까지 | 1, 2, 3 |
(1..=3).rev() | 거꾸로 | 3, 2, 1 |
0..n 은 정확히 n 번 돈다. 0 부터 세는 배열 번호와 잘 맞는다. 끝 숫자까지 넣고 싶으면 ..= 를 쓴다. .rev() 는 범위를 뒤집는 메서드다.
1 부터 100 까지 더하는 것도 범위로 바로 쓴다.
fn main() {
let mut total = 0;
for n in 1..=100 {
total = total + n;
}
println!("{total}");
} Compiling sum v0.1.0 (~/projects/sum)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.16s
Running `target/debug/sum`
505003 실습 — n번째 피보나치 수
피보나치 수는 앞의 두 수를 더해 다음 수를 만든다(0, 1, 1, 2, 3, 5, 8, …). 두 수 a·b 를 들고 n 번 앞으로 나아가면 a 가 n번째 수다.
fn fib(n: u32) -> u64 {
let mut a = 0;
let mut b = 1;
for _ in 0..n {
let next = a + b;
a = b;
b = next;
}
a
}
fn main() {
for n in [1, 2, 10, 50] {
let value = fib(n);
println!("fib({n}) = {value}");
}
} Compiling fib v0.1.0 (~/projects/fib)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.17s
Running `target/debug/fib`
fib(1) = 1
fib(2) = 1
fib(10) = 55
fib(50) = 12586269025for _ in 0..n은 n 번 돈다. 꺼낸 값을 쓰지 않으니 이름 자리에_를 둔다.fib(50)은 120억이 넘어서i32(약 21억까지, 5편)에는 안 들어간다. 그래서 반환 타입을u64로 했다.- 함수 마지막 줄
a에는 세미콜론이 없다. 이 값이 반환값이다(11편).
여기까지 함수·if·for 를 모두 쓰면, 11편의 온도 변환을 여러 온도에 한꺼번에 돌릴 수 있다.
fn to_fahrenheit(c: f64) -> f64 {
c * 9.0 / 5.0 + 32.0
}
fn main() {
for c in [10.0, 25.0, 35.0] {
let f = to_fahrenheit(c);
let note = if f >= 86.0 { "덥다" } else { "선선하다" };
println!("{c}℃ = {f}℉ {note}");
}
} Compiling convert v0.1.0 (~/projects/convert)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.18s
Running `target/debug/convert`
10℃ = 50℉ 선선하다
25℃ = 77℉ 선선하다
35℃ = 95℉ 덥다[10.0, 25.0, 35.0] 배열을 for 로 돌면서 함수를 부르고, if 로 낸 말을 찍었다. 이것으로 기본 문법이 끝났다. 다음 편부터는 Rust 를 다른 언어와 가르는 개념, 소유권을 다룬다.