Rust 为什么有时候我的\u arc\u mutex.clone()在使用完之前会被释放?

Rust 为什么有时候我的\u arc\u mutex.clone()在使用完之前会被释放?,rust,Rust,我得到了这个错误: --> src/client.rs:189:22 | 189 | let client = client.clone().lock().unwrap(); | ^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement | |

我得到了这个错误:

   --> src/client.rs:189:22
    |
189 |         let client = client.clone().lock().unwrap();
    |                      ^^^^^^^^^^^^^^                - temporary value is freed at the end of this statement
    |                      |
    |                      creates a temporary which is freed while still in use
对于这个太大的函数,我无法发布一个最小的可复制示例:

async fn send_and_expect<T: OnEvent<T>>(
        client: Arc<Mutex<Self>>,
        request: rtsp_types::Message<Body>,
        unauthorized_retry: i32,
    ) -> std::result::Result<rtsp_types::Response<Body>, ClientActionError>
    where
        RtspMachine: OnEvent<T>,
        T: From<Response>,
    {
        let expected_cseq = client_parse_cseq(&request)?;
        let mut client = client.lock().unwrap();
但是这个编译没问题


怎么了?为什么
client.clone()
有时会在使用完成之前释放,但有时不会释放?

不幸的是,您的简短示例太短了,因为它从未绑定
unwrap
ped MutexGuard。为了重现错误,我们需要添加一个绑定():

使用std::sync::{Arc,Mutex};
fn main(){
设a=Arc::new(Mutex::new(0));
让_b=a.clone().lock().unwrap();
}
rustc
现在正派地大喊:

错误[E0716]:借用时丢弃的临时值
-->src/main.rs:5:13
|
5 | let _b=a.clone().lock().unwrap();
|^^^^^^-此语句末尾将释放临时值
|              |
|创建在仍在使用时释放的临时文件
6 | }
|-当删除`_b`并运行'MutexGuard'类型的'Drop'代码时,可以在此处使用借用`
|
=注意:考虑使用一个“让”绑定来创建一个较长的生命值
那么,为什么借钱人会对我们大喊大叫呢?请记住,它引用了
互斥体。此参考源于
Arc
。但是,
clone
d变量只存在到语句末尾:没有与
a.clone()的绑定,它在分号处消失

简单的解决方法是绑定
a.clone()
。通常,您将重用相同的标识符,如():

使用std::sync::{Arc,Mutex};
fn main(){
设a=Arc::new(Mutex::new(0));
设a=a.clone();
让_b=a.lock().unwrap();
}
虽然这在单个
main
函数中似乎很奇怪,但在
将值移动到闭包中时,这种情况更为常见

你可能会说:“等一下。”。“这是一个共享引用,为什么我不能继续使用它?在同一范围内仍然有
a
!”虽然这可能是真的,但这也是一个陷阱。如果要编译
.clone().lock()
行,那么我们可以创建一个释放错误后使用:

a=Arc::new(Mutx::new(0));
设b=a.clone().lock().unwrap();//参考计数器增加和减少1
删除(a);//引用计数器->0:值被释放
*b=10;//哎呀!

Your
main()
如果您尝试使用结果,则示例会给出相同的错误:@kmdreko为什么trust不能使克隆的值一直存在到行尾?它确实存在到行尾。但是,结果是一个
MutexGuard
,它持有对
Mutex
的内部值的引用,因此需要它活得更长。@kmdreko不
让b=
将引用绑定到
b
?我迷路了。这段代码相当于
let b=({let tmp2=({let tmp1=a.clone();tmp1}).lock();tmp2}).unwrap()
let b=
tmp2
绑定到
b
,但是
tmp1
被删除,即使
b
引用了它。
use std::sync::{Arc, Mutex};
fn main() {
    let a = Arc::new(Mutex::new(0));
    a.clone().lock().unwrap();
}