I have a routine that plays with objects in a container and references to those objects stored in another 2 containers.
However, I am not finding the rust way of doing this, the lifetime inference seems to forbid this and I don't know how to resolve it
fn main() {
let mut deck : Deck = Deck::new();
let mut p1 : Hand = Hand::new();
let mut p2 : Hand = Hand::new();
do_hands(|data: &[Card]| -> Result<(),()> {
for card in data {
deck.insert(card.id, CardCell::new(*card));
let card: &CardCell = deck.get_mut(&card.id).unwrap();
handle_hand(&mut card, &mut p1, &mut p2);
}
return Ok(());
});
}
Here is the full playground link: https://play.rust-lang.org/?gist=6079ade83e3fcf06f35397eac2e82d05&version=nightly
I played with the example in the playground and managed to get the code to compile, with the following changes:
Change the signature of handle_hand
The initial signature was fn handle_hand<'a>(_card: &'a mut CardCell, _p1: &mut Hand<'a>, _p2: &mut Hand<'a>)
, but this was what the compiler error is about. This signature requires all input to handle_hand
to have the same lifetime, but that is not the case in your code. There, inside the closure, card
clearly has a shorted lifetime than p1
and p2
. So the revised signature simply becomes: fn handle_hand<'a, 'b>(_card: &'b mut CardCell, _p1: &mut Hand<'a>, _p2: &mut Hand<'a>)
.
Change the signature of card
inside the closure.
Since handle_hand
requires a &mut CardCell
, you must then declare card
as let mut card: &mut CardCell =...
Derive the copy trait into the Card
struct. I put this last since this may need to be changed depending on how you'd further write the struct. But at this point, it's just a wrapper of u64
, and you can simply do #[derive(Clone, Copy]
on it. This is required because the Cell
struct you are using requires a Copy type. Derive works here because all your struct's fields already implement the Copy type.