Dereference Operator

In Rust, the dereference operator (*) is used to access or modify the value that a reference points to. Let's break down the code snippet you provided and explain why the dereference operator is needed on the first line but not on the others:

fn init_board(board: &mut Vec<Vec<char>>, rows: usize, cols: usize) {
    *board = vec![vec!['.'; cols]; rows];
    board[3][3] = 'W';
    board[4][4] = 'W';
    board[3][4] = 'B';
    board[4][3] = 'B';
}

Explanation:

  1. Function Parameter: The function takes a mutable reference to a Vec<Vec<char>> as its first parameter: board: &mut Vec<Vec<char>>. This means that board is not the 2D vector itself but a mutable reference to it.

  2. Dereferencing with *board: The first line of the function is:

    *board = vec![vec!['.'; cols]; rows];

    Here’s why the dereference operator (*) is needed:

    • board is a mutable reference (&mut Vec<Vec<char>>). To modify the actual value that board points to, you need to dereference it using *board.

    • *board gives you access to the Vec<Vec<char>> itself, allowing you to assign a new value to it.

    • Without the dereference, if you just wrote board = vec![vec!['.'; cols]; rows];, it would mean you're trying to change what the board reference itself points to, which is not allowed. Instead, *board = ... tells the compiler to modify the content that board points to.

  3. Accessing Elements with board[3][3]: After initializing board with the new value, the rest of the lines are:

    board[3][3] = 'W';
    board[4][4] = 'W';
    board[3][4] = 'B';
    board[4][3] = 'B';

    Here's why you don’t need the dereference operator for these lines:

    • When you access elements of a vector using index notation (e.g., board[3][3]), Rust automatically dereferences the vector for you. This is because board is already a reference to a Vec<Vec<char>>, so when you use the [] indexing, Rust knows how to access the inner elements without explicit dereferencing.

    • Since board is a mutable reference (&mut Vec<Vec<char>>), you can directly modify its elements (e.g., board[3][3] = 'W';) without needing *board[3][3] = 'W';.

Summary:

  • First Line: *board = ... is needed because you are reassigning the entire vector that board points to. This requires dereferencing the reference to get to the value it points to.

  • Rest of the Lines: You are accessing and modifying elements within the vector, so no explicit dereference is needed—Rust handles it automatically with the [] index notation.

This distinction helps to ensure safety and clarity when working with references and mutable references in Rust.

Last updated