如何在 Rust 中创建一个 RwLock 向量?

3
我需要创建一个结构体的向量。该向量的每个元素都需要由RwLock进行保护,以便线程可以通过RwLock对其进行读写操作。在Rust中应如何实现?
我尝试使用Arc向量来实现。
#[derive(Default, Debug, Clone, Copy)]
pub struct shared_values {
    x: usize,
    y: usize,
}

fn main() {
    let mut shared = vec![Arc::new(RwLock::new(shared_values { x: 0, y: 0 })); 10];

    //changing value of the element [0]
    {
        let mut sh = shared[0].write().unwrap();
        *sh = shared_values { x: 10, y: 10 };
    }

    //Printing
    {
        println!("Print RwLock");
        for i in 0..g.ns {
            {
                let val = shared[i].read().unwrap();
                println!("{:?}", val);
            }
        }
    }
}

结果如下:
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }
RwLockReadGuard { lock: RwLock { data: shared_values { suitor: 10, ws: 10 } } }

我期望元素0被设置为{x:10,y:10}

我认为Arc会增加shared_values {x:0,y:0}的计数引用,但不会为向量中的每个索引创建独立的元素。


1
请注意,类型应该使用 PascalCase 写法。 - Boiethios
1个回答

4
这个向量初始化克隆了参数。请使用std::iter::repeat_with
use std::sync::{Arc, RwLock};

#[derive(Default, Debug, Clone, Copy)]
pub struct SharedValues {
    x: usize,
    y: usize,
}

fn main() {
    let shared: Vec<_> =
        std::iter::repeat_with(|| Arc::new(RwLock::new(SharedValues { x: 0, y: 0 })))
            .take(10)
            .collect();

    //changing value of the element [0]
    {
        let mut sh = shared[0].write().unwrap();
        *sh = SharedValues { x: 10, y: 10 };
    }

    //Printing
    {
        println!("Print RwLock");
        for x in shared {
            println!("{:?}", x.read().unwrap());
        }
    }
}

如果您想念宏的简单性,那么您可以编写自己的宏:

macro_rules! vec_no_clone {
    ( $val:expr; $n:expr ) => {{
        let result: Vec<_> = std::iter::repeat_with(|| $val).take($n).collect();
        result
    }};
}

fn main() {
    let shared = vec_no_clone![Arc::new(RwLock::new(SharedValues { x: 0, y: 0 })); 10];
}

1
谢谢,这正是我想要的。 :) - Kandah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接