非レキシカルライフタイムの後
元のコードは Rust 2018 でそのまま動作し、 non-lexical-lifetimesを有効にします:
fn main() {
let mut vector: Vec<i32> = Vec::new();
if let Some(last_value) = vector.last() {
vector.push(*last_value + 1);
}
}
借用チェッカーが改善され、新しい値をプッシュするためlast_value
に必要な変更可能な借用と参照が重複しないことが認識されました。vector
HashMap または Vec から参照を返すと、借用がそのスコープを超えて持続しますか? を参照してください。借用チェッカーがまだ十分に賢く処理できない同様のケース (Rust 1.32 の時点)。
非レキシカルライフタイムの前
の結果はvector.last()
ですOption<&i32>
。その値の参照は、ベクトルを借用したままにします。ベクトルにプッシュする前に、ベクトルへのすべての参照を取り除く必要があります。
ベクトルにCopy
有効な値が含まれている場合は、ベクトルから値をコピーして、借用をより早く終了します。
fn main() {
let mut vector: Vec<i32> = Vec::new();
if let Some(&last_value) = vector.last() {
vector.push(last_value + 1);
}
}
Some(&last_value)
ここでは、 の代わりにパターンを使用しましたSome(last_value)
。これにより、参照が分解され、コピーが強制されます。できない型でこのパターンを試すとCopy
、コンパイラ エラーが発生します。
error[E0507]: cannot move out of borrowed content
--> src/main.rs:4:17
|
4 | if let Some(&last_value) = vector.last() {
| ^----------
| ||
| |hint: to prevent move, use `ref last_value` or `ref mut last_value`
| cannot move out of borrowed content
ベクターに可能な型が含まれていない場合はCopy
、最初に値を複製することをお勧めします。
fn main() {
let mut vector: Vec<String> = Vec::new();
if let Some(last_value) = vector.last().cloned() {
vector.push(last_value + "abc");
}
}
.map()
または、呼び出しがベクトルから借用しない値を返すように、別の方法で値を変換することもできます。
fn main() {
let mut vector: Vec<String> = Vec::new();
if let Some(last_value) = vector.last().map(|v| v.len().to_string()) {
vector.push(last_value);
}
}