2017-03-28 3 views
-1

は、私が画面にそれをプリントアウトしながら、変数varをインクリメントインプレース割り当てを行うことができます。Rustでインプレースアサインメントを行う方法は? C++で

int var = 5; 
std::cout << (var += 1) << std::endl; 

錆がで/デクリメント演算子++ & --を持っていないので、私はこれをやっています。私は錆でそれを試してみました:

let mut counter = 0; 
println!("{}", (counter += 1)); 

それは言っている:

error[E0277]: the trait bound `(): std::fmt::Display` is not satisfied 
--> src/main.rs:3:20 
    | 
3 |  println!("{}", (counter += 1)); 
    |     ^^^^^^^^^^^^^^ the trait `std::fmt::Display` is not implemented for `()` 
    | 
    = note: `()` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string 
    = note: required by `std::fmt::Display::fmt` 

答えて

5

ルスト代入演算子は、割り当てられた値に評価されていません。彼らは()と評価されます。したがって、新しい値を取得するために、代入後に変数を読み取る必要があります。ブロックは式でもあるので、ブロックでこれを行うことができます。あなたは、多くの場合、これをやろうとしている場合は

let mut counter = 0; 
println!("{}", { counter += 1; counter }); 

、マクロを定義することを検討:

macro_rules! inc { 
    ($e:expr) => { 
     { $e += 1; $e } 
    } 
} 

let mut counter = 0; 
println!("{}", inc!(counter)); 
4

最短ソリューションは値を返すことです:

let mut counter = 0; 
println!("{}", {counter += 1; counter}); 

しかし、正直なところ、私は希望これは慣用錆ではないと言って、別の行に書くこともできます:

let mut counter = 0; 
counter += 1; 
println!("{}", counter); 

これ以上の回答は、割り当ての価値を得ることができないということです。 AddAssignための形質は、特に、メソッドから返される値がない

pub trait AddAssign<Rhs = Self> { 
    fn add_assign(&mut self, Rhs); 
} 

として定義されます。 は一般にが1つではないため、Rustは割り当て結果に有用な値を持ちません。所有権セマンティクスは、let x = String::new();のようなものの「戻り値」が何であるべきかを理解することを複雑にします。それがStringだった場合は、xが所有権に何が起こったでしょうか?

すべての式は、一部型を返すので、割り当てはまた、ユニットタイプとして知られている、空のタプル(())を返します。

の場合、の場合、値は整数であり、Copy特性を実装します。つまり、ブロックからコピーを自明に返すことができます。

同じ溶液がStringのための「仕事」だろう、あなたは後でそれを使用しようとするまで:

参照を返すことによって固定することができ
let mut string = String::new(); 
println!("{}", {string += "a"; string}); 
println!("{}", string); // use of moved value: `string` 

println!("{}", {string += "a"; &string}); 

しかし、この時点で実際には「節約」は行われません。

関連する問題