8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rust】loopとwhile trueの違い

Last updated at Posted at 2020-08-08

loop != while true

意味的な違いはないと思われるloop {...}while true {...}だが、変数制約チェックなどのパス解析では扱いが異なる。

// loopだとコンパイルできる
fn main() {
    let mut a = 1;
    let mut b = 2;
    let mut x = &mut a;
    println!("{}", x);

    loop {
        x = &mut b;
        break;
    }
    let y = &mut a;
    println!("{} {}", x, y);
}
// while trueだとコンパイルできない
fn main() {
    let mut a = 1;
    let mut b = 2;
    let mut x = &mut a;
    println!("{}", x);

    while true {
        x = &mut b;
        break;
    }
    let y = &mut a; // ERROR: second mutable borrow occurs here
    println!("{} {}", x, y);
}

xによるaの可変参照はループブロック内のx = &mut b;によって解放されるが、whileではブロックが実行されない可能性も考慮されるため、ループ後のyに割り当てることができない。一方loopでは確実に解放されるとみなされるため、aの可変参照はyに割り当て可能と判定される。

上のようなwhile trueは単純にloopに置き換えるだけで解決するが、他言語でみられる以下のようなパターンもwhileのかわりにloop(+break)を使うべき事例があるかもしれない。

// 必ず1度は実行されるループ(do-whileなんてなかった)
let mut found = false;
while !found { // 見つかるまでループ
    // 前処理
    ...
    // 検索
    found = ...
    // 後処理
    ...
}

おまけ

// loopでも途中で抜ける素振りを見せるとコンパイルできない
fn main() {
    let mut a = 1;
    let mut b = 2;
    let mut x = &mut a;
    println!("{}", x);

    loop {
        if false { break; } // ここでbreakするかも(しない)
        x = &mut b;
        break;
    }
    let y = &mut a; // ERROR: second mutable borrow occurs here
    println!("{} {}", x, y);
}

たとえ0%でも可能性は見逃さない。

8
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?