rustsmart-pointersrefcell

Changing contents of an array via its reference


I've been recently working with the following scenario:

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
    }

Given a function that takes as input a reference to an immutable u32 array, I'm trying to change its contents via a smart pointer. I'm still kind of new to interior mutability concept; the snipped above has the following issue:

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

I'm not entirely sure what is the correct pattern here. Any ideas? thanks!


Solution

  • You can't change anything behind a shared reference unless it is already in a UnsafeCell (for example via RefCell). The most likely version you want is to take a mutable reference instead:

    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;
        }
    }
    

    If you want to use interior mutability, the parts that you want to mutate have to be wrapped in a struct supporting that already. So you could take &[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;
        }
    }
    

    or &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;
        }
    }