53170


Vecをthreadで利用するコードを書いた所  
cannot borrow as mutableとエラーが出ました。  
エラーコード(E0596)にはmutが必要と書いてありますがmutはつけています。  
どの様にすればエラーが取れますでしょうか？

[code]

    use std::vec::Vec;
    use std::sync::Arc;
    use std::{thread,time};
    
    fn main() {
        let arc: Arc<Vec<i32>> = Arc::new(Vec::new());
    
        let mut _arc = Arc::clone(&arc);
        thread::spawn(move || {
            for x in 1..=10 {
                _arc.push(x);
            }
        });
    
        thread::sleep(time::Duration::from_secs(3));
        arc.iter().map(|n| println!("{:?}",n));
    }
    
[/code]

[code]

    error[E0596]: cannot borrow data in a `&` reference as mutable
      --> src/main.rs:11:13
       |
    11 |             _arc.push(x);
       |             ^^^^ cannot borrow as mutable
    
    
[/code]


CC BY-SA 4.0
2019-03-03T10:54:33.963
53168
2019-03-03T11:48:47.283
32285
question
rust
ArcとVecのmutableエラー'cannot borrow as mutable'について


`Arc`で包んだデータは不変の参照としてしかアクセスできません。データを可変にするには、`Arc`で包む前に内部可変性を提供するコンテナで包んでおく必要があります。複数スレッドからのアクセスに対応しているのは`RwLock`や`Mutex`などです。`RwLock`を使うと以下のようになります。

[code]

    use std::sync::{Arc, RwLock};
    use std::vec::Vec;
    use std::{thread, time};
    
    fn main() {
        let arc = Arc::new(RwLock::new(Vec::new())); // Arc<RwLock<Vec<i32>>>型
    
        let arc2 = Arc::clone(&arc);
        thread::spawn(move || {
            for x in 1..=10 {
                if let Ok(mut v) = arc2.write() {
                    v.push(x);
                }
            }
        });
    
        thread::sleep(time::Duration::from_secs(3));
        if let Ok(v) = arc.read() {
            v.iter().for_each(|n| println!("{:?}", n));
        };
    }
    
[/code]

内部可変性についてはこちらのドキュメントが参考になると思います。  
<https://doc.rust-jp.rs/book/second-edition/ch15-05-interior-mutability.html>

また手前味噌ですが、以前このような記事も書きましたので、よかったら参考にしてください。  
<https://qiita.com/tatsuya6502/items/bed3702517b36afbdbca>


CC BY-SA 4.0
2019-03-03T11:48:47.283
53170
2019-03-03T11:48:47.283
14101
53168
answer