首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建一个在仍在使用时释放的临时

创建一个在仍在使用时释放的临时
EN

Stack Overflow用户
提问于 2020-12-20 22:21:55
回答 1查看 620关注 0票数 1

我正在创建一个探索变量生命周期和线程的小应用程序。我想加载一个文件,然后在一个单独的通道中使用它的内容(在本例中是一个音频文件)。我有价值生命周期方面的问题。

我几乎可以肯定,到目前为止我所拥有的语法(用于创建静态变量)是错误的,但是我找不到任何关于File类型和生命周期的资源。到目前为止,我得到的结果是这个错误:

代码语言:javascript
复制
let file = &File::open("src/censor-beep-01.wav").unwrap();
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
 let x: &'static File = file;
               ------------- type annotation requires that borrow lasts for `'static`

我目前拥有的代码是:

代码语言:javascript
复制
#![allow(dead_code)]
#![allow(unused_imports)]
#![allow(unused_must_use)]
#![allow(unused_variables)]

use std::io::{self, BufRead, BufReader, stdin, Read};
use std::sync::mpsc::{self, TryRecvError};
use std::thread;
use std::time::Duration;
use std::fs::File;
use std::rc::Rc;
use rodio::Source;

fn main() {
    let file = &File::open("src/censor-beep-01.wav").unwrap();
    let x: &'static File = file;
        loop {
        let (tx, rx) = mpsc::channel();
        thread::spawn(move || loop {
            let tmp = x;
            let (stream, stream_handle) = rodio::OutputStream::try_default().unwrap();
            let source = rodio::Decoder::new(BufReader::new(tmp)).unwrap();
            stream_handle.play_raw(source.convert_samples());
            match rx.try_recv() {
                Ok(_) | Err(TryRecvError::Disconnected) => {
                    break;
                }
                Err(TryRecvError::Empty) => {
                    println!("z");
                    thread::sleep(Duration::from_millis(1000));
                }
            }
        });

        let mut line = String::new();
        let stdin = io::stdin();
        let _ = stdin.lock().read_line(&mut line);
        let _ = tx.send(());
        return;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-12-20 22:38:12

您需要像Arc::new(Mutex::new(file))一样用ArcMutex包装文件,然后在将其传递给线程之前克隆该文件。

Arc用于引用计数,这是跨线程共享目标对象(在您的例子中是一个文件)所需的,并且需要Mutex来同步访问目标对象。

示例代码(我简化了您的代码,使其更易于理解):

代码语言:javascript
复制
let file = Arc::new(Mutex::new(File::open("src/censor-beep-01.wav").unwrap()));
    loop {
        let file = file.clone();
        thread::spawn(move || loop {
            let mut file_guard = match file.lock() {
                Ok(guard) => guard,
                Err(poison) => poison.into_inner()
            };
            let file = file_guard.deref();
            // now you can pass above file object to BufReader like "BufReader::new(file)"
        });
    }

creates a temporary which is freed while still in use错误的原因:您只存储了文件的引用,而没有存储实际的文件对象。因此,对象将被拖放到该行本身中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65380891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档