How could I assign a value to the mutable reference of a function?

Is there any way to assign a value to the mutable reference of a function return?

#[derive(Clone)]
struct IMG{
    x: u128,
    y: u128,
    px: Vec<u8>
}

impl IMG {
    fn new(x: u128, y: u128) -> Self {
        if x == 0 || y == 0 { return Self {x: 0, y:0, px: Vec::new()} }
        let xyc     = x * y;
        let mut ans = Self {x, y, px: Vec::new()};
        ans.px.resize(xyc as usize, 0u8);
        ans
    }

    fn pos(&mut self, x: u128, y: u128) -> &mut u8 {
        let ln = x * self.y;
        &mut self.px[(ln + y) as usize]
    }
}

fn main() {
    let tmp = &mut IMG::new(3, 3);
    println!("{}", tmp.pos(0, 2)); // it works
    /* This is an invalid operation
     * Rust compiler - invalid left-hand side of assignment
     */
    // tmp.pos(1, 1) = 16;
}

Is this behavior unsafe?

To assign to the location behind a mutable reference you need to dereference it (the compiler actually gives this suggestion):

*tmp.pos(1, 1) = 16;

There are also various other issues with your code: usize should be used rather than u128 if you are indexing into a Vec, and there are some missing mut and &mut. Fixing those gives:

struct IMG{
    x: usize,
    y: usize,
    px: Vec<u8>
}

impl IMG {
    fn new(x: usize, y: usize) -> Self {
        if x == 0 || y == 0 { return Self {x: 0, y:0, px: Vec::new()} }
        let xyc = x * y;
        let mut ans = Self {x, y, px: Vec::new()};
        ans.px.resize(xyc, 0u8);
        ans
    }

    fn pos(&mut self, x: usize, y: usize) -> &mut u8 {
        let ln = x * self.y;
        &mut self.px[ln + y]
    }
}

fn main() {
    let tmp = &mut IMG::new(3, 3);
    println!("{}", tmp.pos(0, 2)); // it works
    *tmp.pos(1, 1) = 16;
}

(playground)

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.