fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
let y = x; // x has been moved
say_hello(y);
say_hello(y); // but y has not been moved, it is still usable
change_string(y);
change_string(y);
}
fn say_hello(s: &str) {
println!("Hello {}", s);
}
fn change_string(s: &mut String) {
s.push_str(" Brown");
}
Run Code Online (Sandbox Code Playgroud)
当我分配x到y x已被移动。但是,当我在函数中使用它时,我希望可以移动具有移动语义的东西。但是,我仍然可以在后续调用后使用参考。也许这与 say_hello() 接受不可变引用有关,但 change_string() 接受可变引用但引用仍未移动。
fn say_hello(s: &str) {
println!("Hello {}", s);
}
Run Code Online (Sandbox Code Playgroud)
为什么这样做
fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
say_hello(x);
name.push_str(" Brown");
}
Run Code Online (Sandbox Code Playgroud)
但这不是吗?
fn main() {
let mut name = String::from("Charlie");
let x = &mut name;
name.push_str(" Brown");
say_hello(x);
}
Run Code Online (Sandbox Code Playgroud)
我所做的只是切换两个函数的顺序,但似乎x在这两种情况下都可变地借用了 name,而 push_str 也可变地借用了 name,那么为什么第一个示例编译?
如果我取消调用,say_hello()即使仍然有两个可变借用,为什么两者的顺序无关紧要?
编辑:这相似吗?
fn change_string(s: &mut String) { // s is mutably borrowed but isn't used yet
println!("{}", s.is_empty()); // so the scopes don't overlap even though is_empty …Run Code Online (Sandbox Code Playgroud) 我不明白切片和参考之间的区别。&String和 和有&str什么区别?我在网上读到一些东西,说引用是一个细指针,切片是一个胖指针,但我不知道,似乎无法找到这两个的意思。我知道切片可以强制转换为引用,但它是如何做到的?Deref特质是什么?
在这个函数中parse可以返回一个错误,所以我用它.filter_map(Result::ok)来过滤掉它们。
fn part1(input: &str) {
let sum = input.lines()
.map(|l| l.parse::<u32>())
.filter_map(Result::ok)
.map(|n| n as f32 / 3.0)
.map(|f| f.round())
.map(|f| f as u32 - 2)
.sum::<u32>();
// println!("{}", sum);
println!("{:?}", sum);
}
Run Code Online (Sandbox Code Playgroud)
但是,part1当 parse 给出错误时,我想从函数中返回,有点像使用这样的问号运算符.map(|l| l.parse::<u32>()?)。如果这样做,编译器会给出错误
error[E0277]: the `?` operator can only be used in a closure that returns `Result`
or `Option` (or another type that implements `std::ops::Try`)
--> src/main.rs:64:18
|
64 | .map(|l| l.parse::<u32>()?)
| ----^^^^^^^^^^^^^^^^^
| | |
| …Run Code Online (Sandbox Code Playgroud) 我正在阅读《Rust 编程语言》。在这段代码中,我不明白为什么它必须是args[1].clone()以及为什么不能是&args[1]:
use std::env;
use std::fs;
fn main() {
let args: Vec<String> = env::args().collect();
let config = parse_config(&args);
println!("Searching for {}", config.query);
println!("In file {}", config.filename);
let contents = fs::read_to_string(config.filename)
.expect("Something went wrong reading the file");
println!("With text:\n{}", contents);
}
struct Config {
query: String,
filename: String,
}
fn parse_config(args: &[String]) -> Config {
let query = args[1].clone();
let filename = args[2].clone();
Config { query, filename }
}
Run Code Online (Sandbox Code Playgroud)
书上有解释,但我还是不明白。它说了一些关于结构取得所有权的事情。
这和上面的代码一样吗?args[1].clone这就是我更改为时编译器所说的操作&args[1]
fn …Run Code Online (Sandbox Code Playgroud)