为什么 Option<T>::and_then() 与后面的 .unwrap_or() 不互斥?
Why is Option<T>::and_then() not mutually exclusive from a following .unwrap_or()?
为什么 Option::and_then() 不专门处理后面的 Option::unwrap_or()? and_then() 不应该仅在选项为 Some() 时发生,然后 .unwrap_or() 仅在选项为 None 时发生吗?这是一个代码示例,第一种方法会触发借用检查器的投诉,而后面的方法不会,但理论上他们不应该做同样的事情吗?
use std::collections::HashMap;
#[derive(Debug)]
struct Response {
account: String,
status: String,
error: String,
}
fn main() {
let num = String::from("426238");
let record = {
Response {
account: "".into(),
status: "failed".into(),
error: "Invalid Account".into(),
}
};
let mut acct_map = HashMap::new();
acct_map.insert(&num, record);
// Doesn't work
let record = acct_map.remove(&num)
.and_then(|mut r| {r.account = num; Some(r)}) // Should only get processed if there's a Some()
.unwrap_or( // Should only get processed if there's a None
Response {
account: num,
status: String::from("failed"),
error: String::from("The server did not return a response for this account."),
}
); // Yet rustc says variable moved from .and_then()
// Works
let num = String::from("426238");
let record = if let Some(mut response) = acct_map.remove(&num) {
response.account = num;
response
} else {
Response {
account: num,
status: String::from("failed"),
error: String::from("The server did not return a response for this account."),
}
};
}
在尝试前者时收到投诉后,我切换到后者,因为它更容易理解并且确实有效,但我想知道 .and_then() 和 .[ 后面是否还有更多内容=21=]() 比我理解的要多。
首先,由于你使用的是unwrap_or
而不是unwrap_or_else
,所以unwrap_or
的参数总是被执行,也就是说总是搬出num
.
其次,即使您使用了 unwrap_or_else
,and_then
或 unwrap_or_else
的签名中也没有任何内容告诉借用检查器这些方法是互斥的,因此在它看来,两个 lambda 都可以执行。这是不允许的。
if let
是去这里的路。
您 and_then()
中使用的闭包按值捕获 num
。虽然 .unwrap_or()
的执行与将 num
赋值给 r.account
是互斥的,但变量仍然被移入闭包的范围。
为什么 Option::and_then() 不专门处理后面的 Option::unwrap_or()? and_then() 不应该仅在选项为 Some() 时发生,然后 .unwrap_or() 仅在选项为 None 时发生吗?这是一个代码示例,第一种方法会触发借用检查器的投诉,而后面的方法不会,但理论上他们不应该做同样的事情吗?
use std::collections::HashMap;
#[derive(Debug)]
struct Response {
account: String,
status: String,
error: String,
}
fn main() {
let num = String::from("426238");
let record = {
Response {
account: "".into(),
status: "failed".into(),
error: "Invalid Account".into(),
}
};
let mut acct_map = HashMap::new();
acct_map.insert(&num, record);
// Doesn't work
let record = acct_map.remove(&num)
.and_then(|mut r| {r.account = num; Some(r)}) // Should only get processed if there's a Some()
.unwrap_or( // Should only get processed if there's a None
Response {
account: num,
status: String::from("failed"),
error: String::from("The server did not return a response for this account."),
}
); // Yet rustc says variable moved from .and_then()
// Works
let num = String::from("426238");
let record = if let Some(mut response) = acct_map.remove(&num) {
response.account = num;
response
} else {
Response {
account: num,
status: String::from("failed"),
error: String::from("The server did not return a response for this account."),
}
};
}
在尝试前者时收到投诉后,我切换到后者,因为它更容易理解并且确实有效,但我想知道 .and_then() 和 .[ 后面是否还有更多内容=21=]() 比我理解的要多。
首先,由于你使用的是unwrap_or
而不是unwrap_or_else
,所以unwrap_or
的参数总是被执行,也就是说总是搬出num
.
其次,即使您使用了 unwrap_or_else
,and_then
或 unwrap_or_else
的签名中也没有任何内容告诉借用检查器这些方法是互斥的,因此在它看来,两个 lambda 都可以执行。这是不允许的。
if let
是去这里的路。
您 and_then()
中使用的闭包按值捕获 num
。虽然 .unwrap_or()
的执行与将 num
赋值给 r.account
是互斥的,但变量仍然被移入闭包的范围。