gpt4 book ai didi

rust - 如何更改结构中 Arc 的值?

转载 作者:行者123 更新时间:2023-11-29 08:22:38 27 4
gpt4 key购买 nike

我无法在结构中递增一个值。我收到很多不同的编译错误。我有一个对 self 的不可变引用,但我无法使其可变。

这是我的结构:

/// Proposer factory.
pub struct ProposerFactory<C, A>
where
A: txpool::ChainApi,
{
/// The client instance.
pub client: Arc<C>,
/// The transaction pool.
pub transaction_pool: Arc<TransactionPool<A>>,
/// The inherents pool
pub inherents_pool: Arc<InherentsPool<<A::Block as BlockT>::Extrinsic>>,
/// Current queue number
cur_queue_no_ptr: Arc<u64>,
}

我想将 cur_queue_no_ptr 增加 +1

我试过这段代码:

let old_value_ref = Arc::get_mut(&mut self.cur_queue_no_ptr).unwrap();
let old_value = *old_value_ref;
let new_value = old_value + 1;

但是出现了这个错误:

    152 |         let old_value_ref=Arc::get_mut(&mut self.cur_queue_no_ptr).unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable

我试过这段代码:

let copied_arc = Arc::clone(&self.cur_queue_no_ptr);
let old_value = *Arc::make_mut(&mut copied_arc);
let new_value = old_value + 1;

还有一个错误:

150 |         let old_value = *Arc::make_mut(&mut copied_arc);
| ^^^^^^^^^^^^^^^ cannot borrow as mutable

我也试过 RefCell 但我得到了这个错误:

   ^^^^^ `std::cell::RefCell<u64>` cannot be shared between threads safely

显然文档中的示例只适用于变量而不适用于结构,那么如何使用结构来实现呢?

最佳答案

Arc 只允许您获得对内容的可变引用,前提是您对 Arc 对象本身有可变引用,而 Arc唯一指向它的内容的(所有其他的都已经被删除了)。

你在这里想要的是用于线程安全编码的 RefCell 的等价物之一,即 MutexRwLock .这些将在您借用内容时锁定对内容的访问,以便您可以同时从多个线程安全地访问它们:

use std::sync::{Arc, Mutex};

fn example() {
// defining the counter variable
let counter = Arc::new(Mutex::new(0));

// lock the mutex to borrow
// it is automatically released when the borrow ends
let mut counter_lock = counter.lock().unwrap();
*counter_lock = *counter_lock + 1;
}

Mutex 只允许您可变地借用,这使它更简单,但有时还不够。 RwLock 也允许您进行不可变借用,因此您可以拥有一个可变借用或多个不可变借用。


或者,对于数字类型,最好使用 atomic types .这些是专门为整数设计的,比 MutexRwLock 更快(因为它们不需要锁定任何东西,更改会自动发生)。对于上面的计数器,相应的示例如下:

use std::sync::{
atomic::{AtomicU32, Ordering},
Arc,
};

fn example() {
// define the counter variable
let counter = Arc::new(AtomicU32::new(0));

// increment the counter
// no lock or mutable borrow is necessary
counter.fetch_add(1, Ordering::SeqCst);
}

关于rust - 如何更改结构中 Arc<u64> 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56228614/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com