E0017

E0017#

警告名: ambiguous_loop_argument

識別子の参照先が曖昧です。ループ変数を指す場合は、パターン内で as <id> を使って束縛してください。ループに入る前の元の値を指す場合は、ループの外で別の束縛名にしてください。

問題のある例#

///|
fn main {
  let a : StringView = "asdf"
  loop a {
    [_, .. d] => {
      println(a)
      //      ^
      // Warning: The usage of 'a' is ambiguous. If it refers to the loop
      // variable, please use `as a` to bind it in the pattern. If it refers to
      // the original value of 'a' before entering the loop, please bind it to a
      // new binder outside the loop.
      continue d
    }
    [] => ()
  }
}

出力:

asdf
asdf
asdf
asdf

a はループに入る前の a の値を参照しているため、値は常に同じになります。

対処#

loop 構文はまもなく削除される予定なので、新しいコードでは可能なら for ループに書き換えることを勧めます。たとえば、次のように書けます。

let text : StringView = "asdf"
for i = 0; i < text.length(); i = i + 1 {
  println(text[i:])
}

既存の loop コードを保守していて、反復ごとに変化するループ変数を参照したい場合は、パターン内で as <id> を使って束縛してください。

///|
fn main {
  let a : StringView = "asdf"
  loop a {
    [_, .. d] as a => {
      println(a)
      continue d
    }
    [] => ()
  }
}

出力:

asdf
sdf
df
f

あるいは、ループに入る前の元の変数値を参照したい場合は、ループの外で別の名前に明示的に束縛してください。

///|
fn main {
  let a : StringView = "asdf"
  let b = a
  loop a {
    [_, .. d] => {
      println(b)
      continue d
    }
    [] => ()
  }
}

出力:

asdf
asdf
asdf
asdf