如何将借用的字符串传递给 Rust 中的外部作用域 Vec?

How to pass a borrowed string into a an outer scoped Vec in Rust?

我一边看书一边尝试学习 Rust。 所以我的程序试图从 macOS 读取 SPDisplaysDataType,我想以某种方式构造这个命令的输出(还不知道如何实现这个,欢迎任何想法)。

现在我似乎无法编译,因为我无法弄清楚这个借用错误。

use std::process::Command;

fn main() {
    let output = Command::new("system_profiler")
        .arg("SPDisplaysDataType")
        .output()
        .expect("Failed getting display data");

    let display_text = String::from_utf8(output.stdout)
        .expect("Cannot read string from output");    

    let mut gpus: Vec<Vec<&str>> = Vec::new();
    let mut gpu_structure: Vec<&str> = Vec::new();

    for (index, line) in display_text.lines().enumerate() {

        if line.contains("Chipset Model") {
            gpus.push(gpu_structure.clone());

            gpu_structure = Vec::new();
            let mut gpu_title_string = format!("{}", index);

            gpu_title_string.push_str(line);

            let cloned = gpu_title_string.clone();
            gpu_structure.push(cloned.as_str());
            continue;
        }
         gpu_structure.push(line);
    }
}

我得到的错误是:

   |
21 |             gpus.push(gpu_structure.clone());
   |                       ------------- borrow later used here
...
29 |             gpu_structure.push(cloned.as_str());
   |                                ^^^^^^ borrowed value does not live long enough
30 |             continue;
31 |         }
   |         - `cloned` dropped here while still borrowed

问题看起来是您试图在内部作用域中克隆一个值,并在外部作用域中存储对该新值的引用。 gpu_structure 正在存储 &str (cloned.as_str()),但是当您退出 if 语句时 cloned 被删除。这里有一些更改,将 &str 的几个实例替换为 String 应该有效。

use std::process::Command;

fn main() {
    let output = Command::new("system_profiler")
        .arg("SPDisplaysDataType")
        .output()
        .expect("Failed getting display data");

    let display_text = String::from_utf8(output.stdout)
        .expect("Cannot read string from output");    

    let mut gpus: Vec<Vec<String>> = Vec::new();
    let mut gpu_structure: Vec<String> = Vec::new();

    for (index, line) in display_text.lines().enumerate() {

        if line.contains("Chipset Model") {
            gpus.push(gpu_structure.clone());

            gpu_structure = Vec::new();
            let gpu_title_string = format!("{}{}", index, line);

            gpu_structure.push(gpu_title_string.clone());
            continue;
        }
         gpu_structure.push(line.to_string());
    }
}

当使用堆分配的数据结构(如 Vec)和非静态字符串时,通常最好使用 String,因为它们更适合借用检查器,并且它们的所有权是比较容易对付。