I have an function param of type args: & std::env::Args, marked in bold in the code:
During the compilation compiler complains about line marked as 1)
pub struct Config<'a>{
pub program_name: &'a String,
pub query: &'a String,
pub file_name: &'a String,
}
impl<'a> Config<'a> {
**pub fn new(args: & std::env::Args)** -> Result<Config, &'static str>
{
if args.count() < 3 {**1) ^^^^ move occurs because `*args` has type `std::env::Args`, which does not implement the `Copy` trait**
return Err("Not enough arguments provided");
}
Ok(Config {
program_name: &args.next().unwrap(),
query: &args.next().unwrap(),
file_name: &args.next().unwrap(),
})
}
}
I really don't understand why would move occur? I'm merely taking the count of the elements, so "in theory" I shouldn't be moving anything and yet apparently I'm moving? Why, and how to fix it?
Could you please tell me which button ^^^ on the toolbar is for the code formatting?
I'm asking because I don't have that char on my keyboard so I'd like to be able to use the tools provided by this forum.
The error occurs because the count method consumes the iterator it is called on. Additionally, your calls to .next() will also fail to compile as you don't have mutable access to the Args iterator, since asking for the next item requires mutating the iterator.
Thanks, I appreciate that help.
The only thing I'm not happy about it is that there is a cloning used, which "theoretically" shouldn't be needed as the "env::args" won't go out of scope until main exits.
If you really want to avoid it, then you’d need to take a mutable reference to the iterator, since progressing through an iterator requires mutating it
If you use references in the above, then the Config struct would not have ownership of the variables, and some other value would have to actually store the strings. As you can see in @notriddle's example, you can still avoid the clone even when not using references.
You can just take the Vec by value, and then you can both access its .len() without consuming it, and then also remove elements from it one-by-one (eg. using into_iter() or pop() or swap_remove() etc.)