通过引用更改数组的内容

Changing contents of an array via its reference

提问人:sdgaw erzswer 提问时间:3/20/2023 更新时间:3/20/2023 访问量:57

问:

我最近一直在处理以下场景:

pub fn random_function(inp_array: &[u32]) {

    for actual_val in (RefCell::new(*inp_array)).iter_mut() {
        // change actual_val to e.g., constant number so that it's reflected in inp_array
    }

给定一个函数将对不可变的 u32 数组的引用作为输入,我正在尝试通过智能指针更改其内容。我对内部可变性概念仍然有点陌生;上面的截图存在以下问题:

error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
error[E0599]: no method named `iter_mut` found for struct `RefCell` in the current scope

我不完全确定这里的正确模式是什么。有什么想法吗?谢谢!

Rust 智能指针 refcell

评论

1赞 Filipe Rodrigues 3/20/2023
你不能在不引起 U.B. 的情况下更改 a,您需要接受 a 或类似的东西。(即内部可变性需要在参数中明确)&[u32]&RefCell<Vec<u32>>

答:

2赞 cafce25 3/20/2023 #1

您不能更改共享引用后面的任何内容,除非它已经位于 (例如,via )。您想要的最可能的版本是改为采用可变引用:UnsafeCellRefCell

pub fn random_function(inp: &mut [u32]) {
    for actual_val in inp {
        // change actual_val to e.g., constant number so that it's reflected in inp_array
        *actual_val += 10;
    }
}

如果要使用内部可变性,则必须将要更改的部分包装在已经支持该可变性的结构中。所以你可以采取&[RefCell<u32>]

use std::cell::RefCell;
pub fn random_function(inp: &[RefCell<u32>]) {
    for actual_val in inp {
        // change actual_val to e.g., constant number so that it's reflected in inp_array
        *actual_val.borrow_mut() += 10;
    }
}

&RefCell<impl AsMut<[u32]>>

use std::cell::RefCell;
pub fn random_function(inp: &RefCell<impl AsMut<[u32]>>) {
    for actual_val in inp.borrow_mut().as_mut() {
        // change actual_val to e.g., constant number so that it's reflected in inp_array
        *actual_val += 10;
    }
}

评论

0赞 sdgaw erzswer 3/20/2023
谢谢,这个答案澄清了我遗漏的方面。事实上,重写上游,使这可能是一个简单的 &mut 数组,而不是通过单元格使事情复杂化,这是最明智的解决方案。谢谢!
1赞 Finomnis 3/20/2023 #2
  • “将对不可变 U32 的引用作为输入”
  • “试图改变其内容”

这两种说法是不相容的。如果没有 ,则无法改变对不可变变量的引用。即便如此,这也是不合理的unsafe

如果您的函数需要修改 中的值,它必须将其作为 .inp_array&mut [u32]

当然,您可以使用内部可变性来实现此目的,但类型必须是 or 或它们各自的 ref-counted 对应项,或者 。&RefCell&MutexRc<RefCell>Arc<Mutex>