Reference in associated type

Hi,

I have a simple problem, but I am not sure how to solve in an elegant and idiomatic way.

I would like to implement a grid where each cell can be solid or empty.
So I have the following code:

use std::collections::HashMap;
use std::ops::Index;

#[derive(Copy, Clone, Hash, PartialEq, Eq)]
struct Position {
    x: i32,
    y: i32,
}

enum CellType {
    Solid,
    Empty,
}

struct Grid {
    cells: HashMap<Position, CellType>
}

Then I was thinking to implement the Index trait in order to be able to access the grid cell in a easy way, but here I found an issue:

impl Index<Position> for Grid {
    type Output = Option<CellType>;

    fn index(&self, position: Position) -> Self::Output {
        self.cells.get(&position)
    }
}

This doesn't compile since HashMap::get returns Option<&CellType>, but I cannot use reference in associated type lifetime (AFAIK).
So I was wondering which is the best approach for a such simple problem.

Thank you.

index returns &Self::Output, so that shouldn't be a problem. In fact, you should receive the corresponding compile error from your code.

If I am not wrong I cannot return &Self::Output because Index::index returns Self::Output

Please check the link to documentation in my previous post. Is this what you're looking for?

Ops, sorry, you're right, anyway the problem is that I should return &Option<&CellType>, but I don't know how to do it, since the associated type Output cannot be linked to a lifetime (AFAIK)

It's not possible to return options from Index. Notice how the other containers also panic when the index is missing.

2 Likes

Argh! So I was trying to do something very anti-idiomatic.
I am going to implement following the standard approach, so index operator will return the reference to the value and panic in case the index is not valid.

type Output = CellType;

fn index(&self, position: Position) -> &Self::Output {
    &self.cells[&position]
}