16

I'm trying to get my head around ownership and the borrow checker. I've run into an issue I've managed to 'solve' but I think there should be a more ergonomic way to do it.

The following code trips the borrow checker, because I'm trying to move file.filepath to thisfile_path while it is in a borrowed context.

for file in &self.filelist {
    let thisfile_path = String::from(file.filepath);
    let this_wd = self.notifier.add_watch(Path::new(&file.filepath), watch_mask::CLOSE_WRITE).unwrap();
    let this_watch = Watchlist {configfile: thisfile_path, watchd: this_wd};
    watches.push(this_watch);
}

&self.filelist is Vec<ConfigFiles> where ConfigFiles is a struct.

I'm iterating through filelist, and I want to copy a field from the ConfigFiles struct to a new Vec.

If I replace that line with let thisfile_path = String::from(&file.filepath); it doesn't work because the trait convert is not implemented for &String.

I've found a workaround, but I don't think it's the ideal way to do this:

let thisfile_path = String::from(&file.filepath[..]);

Is this the only way I can resolve this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
arsalan86
  • 575
  • 2
  • 5
  • 9

2 Answers2

21

std::string::String implements the clone() method, so you could achieve the same thing in a more direct way using:

let thisfile_path = file.filepath.clone();
Florian Weimer
  • 32,022
  • 3
  • 48
  • 92
6

I have no means to try the code right now and I am not that knowledgeable about Rust myself, but I think .to_owned() is what you are looking for. Cloning a reference yields a reference; .to_owned() returns the desired datatype.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
mmatous
  • 482
  • 6
  • 16
  • 4
    *Cloning a reference yields a reference* — only if the referred-to type does not implement `Clone`. *I have no means to try the code right now* — https://play.rust-lang.org/ – Shepmaster Jul 24 '17 at 12:32
  • 1
    I have a similar problem. I prefer this answer, personally, to the one above because I don't want to pay the price of cloning a string. I want to move the string to a struct. After I move the string, I have no use for it anymore because I'm looping. – Frederick Ollinger Jun 06 '18 at 16:54
  • 2
    @FrederickOllinger does `to_owned()` not clone the string? – Michael Dorst Feb 06 '20 at 22:13