Error type `bool` cannot be dereferenced in rust to Vector of structs in Rust lang

Viewed 35

I'm making a maze algorithm using rust and wasm and I have two structs. A maze, and maze has an Vec of a Block struct.

Like this:

pub struct Maze {
    pub cols: usize,
    pub rows: usize,
    pub blocks: Vec<Block>,
    pub stack: Vec<usize>,
}

impl Maze {
    pub fn new(cols: usize, rows: usize) -> Maze {
        let mut maze = Maze {
            cols,
            rows,
            blocks: vec![],
        };

        for y in 0..rows {
            for x in 0..cols {
                maze.blocks.push(Block::new(x, y))
            }
        }

        maze
    }

And the struct Block has an attribute called visited. I want in a struct function of Maze change this value

// in Maze struct impl
    pub fn run(&mut self) {
        let current_index = self.get_current_index();
        let mut current_block = &mut &self.blocks[current_index];

        // .....
        *current_block.visited = true;

In the last line occur an error:

error[E0614]: type `bool` cannot be dereferenced
   --> src/maze.rs:119:17
    |
119 |                 *current_block.visited = true;
    |                 ^^^^^^^^^^^^^^^^^^^^^^

How can I do to change this value?

This is my implementation of Block

pub struct Block {
    pub x: usize,
    pub y: usize,
    pub visited: bool,
}

impl Block {
    pub fn new(x: usize, y: usize) -> Block {
        Block {
            x,
            y,
            visited: false,
        }
    }

How can I do to change the visited value from Maze.run?

1 Answers

There are two problems, one which is the error you see and one which you will encounter next. The problem with

*current_block.visited = true;

is that the precedence of * is lower than ., so you've written code equivalent to)

*(current_block.visited) = true;

which does not compile because the type of the visited field is bool, which indeed cannot be dereferenced. You could write

(*current_block).visited = true;

and that would work, but it's also unnecessary, because in Rust the . operator looks through references, so you only need

current_block.visited = true;

to assign to the visited field of an &mut Block.

The second problem is that you have an extra & here:

let mut current_block = &mut &self.blocks[current_index];

This means current_block is of type &mut &Block. You can never mutate through an & reference, so you need to remove the &, and it is not needed anyway:

let mut current_block = &mut self.blocks[current_index];
Related