2017-04-20 3 views
5

私は錆1.13をインストールしてみました:私はこのファイルをコンパイルするときなぜmutableとして宣言されていない変数が変更されたときにコンパイラはエラーを報告しませんか?

fn main() { 
    let x: u32; 
    x = 10; // no error? 
} 

は、いくつかの警告がありますが、エラーはありません。 xmutと宣言していないので、はエラーを起こさないはずですか?

+10

これは突然の初期化であり、突然変異ではありません。 – ildjarn

+2

錆1.16は現在のバージョンのRustで、1.17は数週間でリリースされるはずです。最新の状態を保つ価値があります。 – Shepmaster

答えて

12

何が書かれていることと同じです。

let x: u32 = 10; 

コンパイラは、その後、それを変異させることを許可しません。あなたが使用しようとすると、それはコンパイラエラーであることを

let x: u32; 
x = 10; 
x = 0; // Error: re-assignment of immutable variable `x` 

注意初期化されていない変数:

let x: u32; 
println!("{}", x); // Error: use of possibly uninitialized variable: `x` 

この機能は、ini実行時の条件に基づいて変数を異なる方法で初期化します。ナイーブ例:

let x: u32; 
if condition { 
    x = 1; 
} else if other_condition { 
    x = 10; 
} else { 
    x = 100; 
} 

しかし、それが初期化されていないことを可能性がある場合、まだそれはまだエラーになります:

let x: u32; 
if condition { 
    x = 1; 
} else if other_condition { 
    x = 10; 
} // no else 
println!("{:?}", x); // Error: use of possibly uninitialized variable: `x` 
+4

慣用的なさびは、ここでは式指向の構文を使用するでしょう: 'let x = if条件{1} else if other_condition {10} else {100};'これらの例では、遅延初期化の必要はありません。 –

+1

@MatthieuM。それは本当だ。しかし、いくつかの条件分岐の中に異なる副作用があった場合、それは奇妙に見えます。その場合、私はこの形式がもっと慣用的であると思います。 –

8

述べたように、これは突然変異ではなく、延期初期設定:

  • 変異は、既存の変数の値を変更する方法について
  • 延期のinitiですalizationはある時点で変数を宣言し、後でそれを初期化することです。 Cとは異なり、誤って初期化されていない変数(またはC++から移動された変数とは違って)を使用しての危険性がないので、変数は、コンパイル時に値を持っているかどうかを

さびコンパイラトラック。


繰延初期化を使用するための最も重要な理由は、スコープです。 Rustの

fn main() { 
    let x; 
    let mut v = vec!(); 

    { 
     x = 2; 
     v.push(&x); 
    } 

    println!("{:?}", v); 
} 

、ボローチェッカーは、参照がダングリング参照を防止する、それが参照値よりも長生きすることができないことを確認します。

これはv.push(&x)xが長くvより住み、そのためv宣言することを必要とすることを意味します。

頻繁には必要ないが、他のソリューションでは実行時チェックが必要になる。

関連する問題