I'm reading the Chapter 13 of the Rust book. It says that cloneing strings is less efficient than accessing them through an iterator (i.e. next()). Comparing the following examples, I've got two questions:
- Does
args.next()move or clone the string intoqueryandfilename? - If it was a move, it would transfer the ownership from something in
env::args()toquery, wouldn't this break other code? If it was a clone, why could be it more efficient than cloning the string directly?
Definition:
struct Config {
query: String,
filename: String,
}
Inefficient Version
fn main() {
let args: Vec<String> = env::args().collect();
let config = Config::new(&args)
}
impl Config {
fn new(args: &[String]) -> Result<Config, &'static str> {
// [...]
let query = args[1].clone();
let filename = args[2].clone();
// [...]
}
}
Better Version
fn main() {
let config = Config::new(env::args())
}
impl Config {
fn new(mut args: std::env::Args) -> Result<Config, &'static str> {
args.next();
let query = match args.next() {
Some(arg) => arg,
None => return Err("Didn't get a query string"),
};
let filename = match args.next() {
Some(arg) => arg,
None => return Err("Didn't get a file name"),
};
// [...]
}
}