Espérons que le titre est exact.

Je voudrais définir un champ sur la structure Node qui se trouve à l'intérieur d'un vecteur. Le nœud est une référence mutable, donc je ne sais pas pourquoi je ne peux pas lui attribuer. Je suppose que je ne déballe pas correctement l'option?

Exemple de code:


#[derive(Debug)]
enum ContentType {
    Big,
    Small,
}

#[derive(Debug)]
struct Node {
    content_type: Option<ContentType>
}

#[derive(Debug)]
struct List {
    nodes: Vec<Node>,
}

impl List {
    fn get_node(&self, index: usize) -> Option<&Node> {
        return self.nodes.get(index);
    }
}

fn main() {

    let list = List {
        nodes: vec![Node {content_type: None}]
    };
    
    let node = &mut list.get_node(0);
    
     println!("{:?}", list);
    
    if let Some(x) = node {
        x.content_type = Some(ContentType::Big)
    }
}

Terrain de jeux: https: //play.rust-lang .org /? version = stable & amp; mode = debug & amp; edition = 2018 & amp; gist = 18bdaf8b903d57dfbf49ebfb3252cf34

Réception de cette erreur:

cannot assign to `x.content_type` which is behind a `&` reference

1
puttputt 6 nov. 2020 à 00:16

2 réponses

Meilleure réponse

L'erreur se réfère spécifiquement au type de retour de get_node, qui est Option<&Node>. Lorsque vous supprimez le contenu de l'option ici:

    if let Some(x) = node {
        x.content_type = Some(ContentType::Big)
    }

x devient &Node, qui n'est pas une référence mutable.

Vous devez modifier get_node pour renvoyer une référence mutable.

impl List {
    // Change to &mut self to borrow mutable items from self, and change the return type.
    fn get_node(&mut self, index: usize) -> Option<&mut Node> {
        return self.nodes.get_mut(index);
    }
}

fn main() {

    let mut list = List {
        nodes: vec![Node {content_type: None}]
    };
    
    // Move this print statement above get_node(), 
    // as you can't get a non mutable reference while you are still holding onto a mutable reference
    println!("{:?}", list);
    
    let node = list.get_node(0);
    
    if let Some(x) = node {
        x.content_type = Some(ContentType::Big)
    }
}

Terrain de jeux

Cela signifie que vous ne pouvez pas obtenir deux références mutables à deux nœuds différents en même temps. Consultez cette question pour une solution potentielle: Comment obtenir des références mutables à deux éléments de tableau en même temps?

3
Prime_Aqasix 5 nov. 2020 à 21:25

Cela signifie ce qu'il dit: get_node renvoie un Option<&Node> - c'est une référence non mutable à un nœud. Vous ne pouvez pas le muter.

Peut-être que tu voulais faire

impl List {
    fn get_node(&mut self, index: usize) -> Option<&mut Node> {
        return self.nodes.get_mut(index);
    }
}

Ensuite, vous pouvez faire

let mut list = List {nodes: vec![Node {content_type: None}]};

let node = list.get_node(0);

if let Some(x) = node {
    x.content_type = Some(ContentType::Big)
}
0
Mike Graham 5 nov. 2020 à 21:24