jradxl
jradxl

Reputation: 555

Don't understand the Move/Copy trait error on this code : Rust

The following code is from an exercise in Packt, Mastering Rust 2nd Edition, but no solution is given. The book is a bit old and perhaps there have been changes in the compiler. The problem is the "word_counter.increment(word);" line where the compiler complains that the Copy trait is not implemented. But I don't see where there is a move.

// word_counter.rs
use std::env;
use std::fs::File;
use std::io::prelude::BufRead;
use std::io::BufReader;
use std::collections::HashMap; 
#[derive(Debug)]
struct WordCounter(HashMap<String, u64>); //A New Type Idiom of Tuple Struct
impl WordCounter {
    pub fn new() -> WordCounter {
        let mut _cmd = WordCounter(HashMap::new());
        _cmd
    }
    pub fn increment(mut self, word: &str) {
        let key = word.to_string();
        let count = self.0.entry(key).or_insert(0);
        *count += 1;
    }
    pub fn display(self) {
        for (key, value) in self.0.iter() {
            println!("{}: {}", key, value);
        }
    }
}
fn main() {
    let arguments: Vec<String> = env::args().collect();
    let filename = &arguments[1];
    println!("Processing file: {}", filename);
    let file = File::open(filename).expect("Could not open file");
    let reader = BufReader::new(file);
    let word_counter = WordCounter::new();
    for line in reader.lines() {
        let line = line.expect("Could not read line");
        let words = line.split(" ");
        for word in words {
            if word == "" {
                continue
            } else {
                word_counter.increment(word);
            }
        }
    }
    word_counter.display();
}

Playground error:

   |
31 |     let word_counter = WordCounter::new();
   |         ------------ move occurs because `word_counter` has type `WordCounter`, which does not implement the `Copy` trait
...
40 |                 word_counter.increment(www);
   |                 ^^^^^^^^^^^^ value moved here, in previous iteration of loop

Upvotes: 1

Views: 438

Answers (1)

Aplet123
Aplet123

Reputation: 35560

The signature of increment is

pub fn increment(mut self, word: &str)

The fact that it is mut self and not &mut self means that the function will consume itself (it moves self into the function). Therefore, the first call moves the value, and the second call is illegal.

Upvotes: 2

Related Questions