Je ne comprends pas l'erreur cannot move out of borrowed content
. Je l'ai reçu plusieurs fois et je l'ai toujours résolu, mais je n'ai jamais compris pourquoi.
Par exemple:
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
produit l'erreur:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ cannot move out of borrowed content
Dans les versions plus récentes de Rust, l'erreur est
error[E0507]: cannot move out of `*line` which is behind a shared reference
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ move occurs because `*line` has type `std::string::String`, which does not implement the `Copy` trait
Je l'ai résolu en clonant line
:
for current_char in line.clone().into_bytes().iter() {
Je ne comprends pas l'erreur même après avoir lu d'autres articles comme:
- Impossible d'emprunter le fichier de & mut self (message d'erreur: impossible de sortir du contenu emprunté)
- Changer un nœud dans un arbre dans Rust
Quelle est l'origine de ce genre d'erreur?
.bytes()
méthode.).as_bytes()
as_bytes()
sans clonage. Mais je ne comprends toujours pas pourquoi?String
obtient labytes
méthode à partir destr
.Réponses:
Regardons la signature pour
into_bytes
:Cela prend
self
, pas une référence à soi (&self
). Cela signifie queself
cela sera consommé et ne sera pas disponible après l'appel. À sa place, vous obtenez un fichierVec<u8>
. Le préfixeinto_
est une manière courante de désigner des méthodes comme celle-ci.Je ne sais pas exactement ce que votre
iter()
méthode renvoie, mais je suppose que c'est un itérateur terminé&String
, c'est-à-dire qu'il renvoie des références à unString
mais ne vous en donne pas la propriété. Cela signifie que vous ne pouvez pas appeler une méthode qui consomme la valeur .Comme vous l'avez trouvé, une solution consiste à utiliser
clone
. Cela crée un objet en double que vous faites propre, et pouvez appelerinto_bytes
sur. Comme d'autres commentateurs le mentionnent, vous pouvez également utiliseras_bytes
ce qui prend&self
, donc cela fonctionnera sur une valeur empruntée. Lequel vous devez utiliser dépend de votre objectif final pour ce que vous faites avec le pointeur.Dans l'ensemble, tout cela a à voir avec la notion de propriété . Certaines opérations dépendent de la possession de l'objet, et d'autres opérations peuvent se permettre d'emprunter l'objet (peut-être mutuellement). Une référence (
&foo
) n'accorde pas la propriété, c'est juste un emprunt.Le transfert de propriété est un concept utile en général - quand j'en ai fini avec quelque chose, quelqu'un d'autre peut l'avoir. Dans Rust, c'est un moyen d'être plus efficace. Je peux éviter d'attribuer une copie, de vous en donner une, puis de jeter ma copie. La propriété est aussi l'état le plus permissif; si je possède un objet, je peux en faire ce que je veux.
Voici le code que j'ai créé pour tester avec:
la source