我有这个工作功能:
fn clear_job(state: State<MyState>) -> Option<String> {
let mut guard = state.job.lock().unwrap();
let maybe_job: &mut Option<Job> = &mut *guard;
// Job is not Copy nor Clone
match maybe_job {
None => None,
Some(job) => match job {
Job::InProgress { .. } => Some("Can't clear in progress job".into()),
_ => {
*maybe_job = None;
Some("Job cleared".into())
},
},
}
}
如果我有None
,我将返回None
;如果我有Some
,我将返回Some
,这就是Option::map()
的确切含义!
我试图重写此功能:
fn clear_job(state: State<MyState>) -> Option<String> {
let mut guard = state.job.lock().unwrap();
let maybe_job: &mut Option<Job> = &mut *guard;
maybe_job.as_ref().map(|job| match job {
Job::InProgress { .. } => "Can't clear in progress job".into(),
_ => {
*maybe_job = None;
"Job cleared".into()
},
})
}
这会给我这个错误:
error[E0500]: closure requires unique access to `maybe_job` but it is already borrowed
--> src/main.rs:113:28
|
113 | maybe_job.as_ref().map(|job| match job {
| --------- --- ^^^^^ closure construction occurs here
| | |
| | first borrow later used by call
| borrow occurs here
...
116 | *maybe_job = None;
| --------- second borrow occurs due to use of `maybe_job` in closure
我有点理解为什么存在错误;我不明白的是,在match
版本中我没有遇到错误,因为从语义上讲,我正在做同样的事情:读入maybe_job
,借用{{1} }(据说也可以在job
上使用),但仍会写入maybe_job
。
为什么我允许使用第一个版本而不允许第二个版本?在这种情况下是否可以使用*maybe_job
?
答案 0 :(得分:1)
我有点理解为什么存在错误;我不明白的是,在
match
版本中我没有遇到错误,因为从语义上讲,我正在做同样的事情:读入maybe_job
,借用{{1} }(据说也可以在job
上使用),但仍会写入maybe_job
。
在匹配情况下,编译器通过在写*maybe_job
之前放下job
上的借位来帮助您。您可以自己进行测试-在执行*maybe_job
之后使用job
,您将显式借用*maybe_job = None
太长时间,编译器将出错。
在job
情况下,作为闭包map
的参数的借用是对|job|
的不可变借用。从闭包中访问变量也是(堆栈中变量的)借用,因此尝试分配给maybe_job
时需要对已经借入的值进行可变借用。
编译器允许一个而不允许另一个的原因仅仅是一个问题,即分析的复杂程度-自动将借用放到*maybe_job
中,编译器必须检测并确保{{1} }是|job|
上的唯一借项-这非常棘手。如果您进行maybe_job.as_ref()
-并且maybe_job
复制不可变的引用会怎样?