2017-04-21 5 views
1

私はstruct型のvecを持っており、ベクトルの最初の要素のいくつかのフィールドを変更したいと思います。これどうやってするの?錆のベクトルの要素のフィールドを変更するにはどうすればよいですか?

例:これはコンパイルに失敗し

struct SomeType { 
    some_value: i32, 
} 

fn main() { 
    let mut vec = Vec::new(); 
    let mut t = SomeType { some_value: 45 }; 
    vec.push(t); 

    println!("Old value: {}", vec.first().unwrap().some_value); 
    vec.first().unwrap().some_value += 1; 
    println!("New value: {}", vec.first().unwrap().some_value); 
} 

error: cannot assign to immutable field 
    --> vec.rs:15:2 
    | 
15 | vec.first().unwrap().some_value += 1; 
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot mutably borrow immutable field 

私はまだルスト可変性のものの周りに私の頭を取得することはできません。ここで正しいアプローチは何でしょうか?

答えて

4

ベクトルの最初の要素を変更するには、通常、その要素への参照を取得します。言い換えれば、参照番号とする。通常の構造であるため、ベクターには参照を提供するメソッドが必要です。

これは、ベクターへの参照は、ベクターの内部で何かを行うこと、それを読んだり、何らかの方法で変更することができることを意味します。錆は細部を知らない、あなたがその参照を保持している間、あなたはものをすることができることを知っているだけです。

そして、その限られた情報だけで、Rustの貸し出しチェッカーは自分を足で撃ってしまうのをやめようとします。それは言う:あなたがベクトルを読むつもりならば、それはあなたが望むどんな方法でもそれを読むことができます、あなたはそれを読む他の関数を作ることさえできます。しかし、あなたがそれを読んでいる間にベクターを変更することはできません。それは安全ではなく、バグにつながります。したがって、ベクトルへの読み取り専用の参照を必要な数だけ持つことができます。ただし、書き込み可能な参照が保持されていない場合とそうでない場合に限ります。書き込み可能な参照を保持している場合は、一度に参照できるのは1つだけです。

このように、参考事項の種類。それで、ベクターには、最初の要素を与える2つの方法、すなわちfirstfirst_mutがあります。

だからここ

let mut vec = Vec::new(); 

あなたのベクトルはすでに変更可能です。また、他の言語から来ても、ベクトルが一度変更可能であれば、常に変更可能であるという直感から作業するかもしれません。 Cの++のconstのようなもの、またはDのimmutableのようなものです。これは変更可能であるか、そうではありません。

しかし、Rustでは、不変な参照を可変構造にしたいことがあります。たとえば、ベクトルの1つの要素と別の要素の別のスレッドで1つのスレッドを動作させ、借用チェッカーの安全ベルトを使用したい場合は、複数の参照を持つ最も簡単な方法は、それらを不変に保つことです。そのため、firstのようなメソッドは不変参照を返し、異なるメソッドを使用して明示的にオプトインする必要がある変更可能な参照を取得するのはこのためです。

P.S.それはどんな助けでしたか?

+0

詳細な説明をありがとうございます!実際にC++から来て、私は '' const''に似たようなことをしようとしました。 –

2

ここ等しく作業のコードサンプル:

vec[0].some_value += 1; 

vec.first_mut().unwrap().some_value += 1; 

最初の要素が、可変基準にfirst()戻る(不変)の基準が必要とされることである質問に示されているコードの問題。

インデックス([0])は、このように動作:スライスに

  • インデキシングをスライスする

    1. vec derefs IndexMut形質
    2. index_mut方法からindex_mut方法は、可変基準(&mut someType
  • +0

    例のおかげで、それは予想よりも簡単です。 ArtemGrの答えを受け入れることに気をつけないことを願っています。なぜなら、彼は非常に分かりにくい説明をしてくれたからです。 –

    0
    を返す呼び出し

    あなたが探していると思います&mut whe nを参照してください。

    #[derive(Debug)] 
    struct Character{ 
        name: String, 
    } 
    
    fn main() { 
        let mut hobbits = vec![ 
         Character{name:String::from("Sam")}, 
         Character{name:String::from("Merry")}, 
         Character{name:String::from("Pepper")}, 
        ]; 
    
        { 
         let third = &mut hobbits[2]; 
         third.name = String::from("Pippin"); 
        } 
    
        println!("{:?}", hobbits); 
    } 
    

    注可変要素参照。変更可能な参照範囲を制限する必要があります。同時に変更可能で不変な参照を持つことはできません。println!は失敗し、thirdはまだスコープ内にあります。

    関連する問題