rust “临时值在借用时丢失”-如何使用路径列表引用?

63lcw9qa  于 12个月前  发布在  其他
关注(0)|答案(3)|浏览(91)

我想发送一个列表(Vec或数组)作为函数参数到一个(Vec)函数。每个Path用于生成一个线程,该线程对该文件执行某些操作。
这里的问题是,我无法找到正确的方法来使引用的寿命足够长。我在函数参数中添加了'static lifetime,因为这在线程中有效。但现在我无法在调用此函数时获得满足此要求的引用。
下面是我的问题的一个小例子。原始代码要复杂得多。

use std::path::{Path, PathBuf};

fn main() {
    // Get paths from somewhere
    let paths = vec![
        PathBuf::from("/path/to/file.txt"),
        PathBuf::from("/path/to/file2.txt"),
    ];

    // Do multithreaded work with these paths
    do_something(&paths.iter().map(|path| path.as_path()).collect::<Vec<_>>());

    // Here some things regarding those files would happen.
}

fn do_something(paths: &'static [&Path]) {
    // Here paths is used again and required to use 'static lifetime
}

个字符

anauzrmj

anauzrmj1#

在您的代码中,&'static Path引用的是用collect创建的时态对象,而不是上面的vec!,这样做应该对您有用,impl Iterator<Item = &'a Path>是对Map<Iter<Cycle<..>>>等不同类型的泛型

use std::path::{Path, PathBuf};

fn main() {
    // Get paths from somewhere
    let paths = vec![
        PathBuf::from("/path/to/file.txt"),
        PathBuf::from("/path/to/file2.txt"),
    ];

    // Do multithreaded work with these paths
    do_something(paths.iter().map(|path| path.as_path()));

    // Here some things regarding those files would happen.
}

fn do_something<'a>(paths: impl Iterator<Item = &'a Path>) {
    // Here paths is used again and required to use 'static lifetime
}

字符串

rryofs0p

rryofs0p2#

如果您只是使用std来生成线程,那么作用域线程也许可以帮助您获得这些路径生存期。
std::thread::scope开始:
与非作用域线程不同,作用域线程可以借用非'static数据,因为作用域保证所有线程都将在作用域的末尾联接。
在您的示例中,运行:

fn do_something(paths: &[&Path]) {
    std::thread::scope(|s| {
        for path in paths {
            s.spawn(move || {
                dbg!(path);
            });
        }
    })
}

字符串

vdzxcuhz

vdzxcuhz3#

下面是使用thread_local!()宏的解决方案:

thread_local! {
    static PATHS: RefCell<Vec<PathBuf>> = RefCell::new(vec![
        PathBuf::from("/path/to/file.txt"),
        PathBuf::from("/path/to/file2.txt"),
    ]);
}

字符串
因为thread_local!()Vec<PathBuf> Package 成RefCell,所以let paths = p.borrow();中的pathsRefCell的借用引用std::cell::Ref<'_, Vec<PathBuf>>
所以这里既不需要克隆也不需要改变do_something()的函数参数的类型:
Playground

相关问题