Notice
Recent Posts
Recent Comments
NeuroWhAI의 잡블로그
[Rust] do-while 본문
MS가 최근 winrt를 Rust로 구현하여 공개했는데 그 예제로 지뢰찾기가 있다.
지뢰찾기 코드를 구경하던 중 아래와 같은 코드(#)를 발견.
Rust는 블럭({ ... })도 식으로 평가하기 때문에 while의 조건식에 블럭을 사용할 수 있는 것을 이용한 꼼수이다.
while {
수행할 내용들;
...
조건식
} { /* 빈 실제 실행문 */ }
찾아보니 거의 6년전(#)에 나온 꼼수인 듯하다.
근데 사실 보기에 그리 좋진 않다.
간단한 매크로를 만들면 좀 더 보기 괜찮아진다.
macro_rules! do_while {
($x:block, $y:expr) => {{
while {
$x;
$y
} {}
}};
}
fn main() {
let mut i = 0;
do_while!({
i += 1;
}, i < 10);
println!("i: {}", i);
}
근데 보기엔 이래도 조건식이기 때문에 break, continue를 쓸 수 없다.
아래와 같이 수정해주면 사용 가능하게 만들 수 있다.
macro_rules! do_while {
($x:block, $y:expr) => {{
loop {
$x;
if !$y {
break;
}
}
}};
}
fn main() {
let mut i = 0;
do_while!({
i += 1;
if i == 5 {
break;
}
}, i < 10);
println!("i: {}", i);
}
하지만 이것도 break에서 값을 반환할 수가 없다는 단점이 있다.
아래와 같이 또 수정해주면 가능은 한데 가독성이 떨어진다.
macro_rules! do_while {
($x:block, $y:expr) => {{
loop {
$x;
if !$y {
break;
}
}
}};
($x:block return $z:expr, $y:expr) => {{
loop {
$x;
if !$y {
break $z;
}
}
}};
}
fn main() {
let mut i = 0;
let z = do_while!({
i += 1;
if i == 5 {
break 42;
}
} return 0, i < 10);
println!("i: {}", i);
println!("z: {}", z);
}
return 대신 뭐 '=>'를 쓴다거나 다른 기호, 단어를 쓰면 좀 나아질지도 모르겠다.
사실 제일 좋은 건 로직을 잘 분석해서 while이나 loop로 대체하는 것이긴 하다..
그리고 이렇게 do-while을 쓸 일이 있을진 모르겠다.
지뢰찾기도 그렇고 찾아보면 do-while이 있는 언어의 코드를 Rust로 포팅할 때 많이들 찾는 것 같다.
'개발 및 공부 > 언어' 카테고리의 다른 글
[Rust] 중첩 Result 사용. (0) | 2020.04.09 |
---|---|
[Rust] Generics와 Associated Types (0) | 2020.04.04 |
[Rust] 직접 block_on 함수 만들기 (포스팅 소개) (0) | 2020.01.31 |
[C++] Concept 맛보기 (1) | 2020.01.10 |
[Rust] Pin과 Unpin 설명. (0) | 2019.09.26 |
Comments