【问题标题】:Converting a Vec<&str> to Vec<&CStr> in rust在 rust 中将 Vec<&str> 转换为 Vec<&CStr>
【发布时间】:2020-01-05 17:16:33
【问题描述】:

看看这个函数:

fn exec(cli: Vec<&str>) {
    eprintln!("execing: {:?}", cli);
    let args: Vec<&CStr> = cli.iter()
        .map(|s| CString::new(s.as_bytes()).unwrap().as_c_str())
        .collect();
    execv(args[0], &args);
    debug(args);
}

它接受Vec&lt;&amp;str&gt; 并将其作为命令执行。我无法将其转换为Vec&lt;&amp;CStr&gt;(这是execv 需要的)。编译器针​​对map 操作报告此错误:

error[E0515]: cannot return value referencing temporary value
   --> src/idea.rs:141:18
    |
141 |         .map(|s| CString::new(s.as_bytes()).unwrap().as_c_str())
    |                  -----------------------------------^^^^^^^^^^^
    |                  |
    |                  returns a value referencing data owned by the current function
    |                  temporary value created here

如何解决这个错误?

【问题讨论】:

  • 您的 map 闭包不能返回对您在闭包中创建的 CString 的字符串引用,因为一旦您从闭包返回,它将无效。只需将 args 设为 CString 的 Vec 即可。从那里你将有更多的类型不匹配需要处理,但一步一步

标签: rust lifetime borrow-checker borrow


【解决方案1】:

您必须将所有 CString 收集到一个单独的向量中,以便您的引用在 execv 调用期间有效:

use std::ffi::CString;
use std::ffi::CStr;

fn main() {
    let cli = vec!["hello", "world"];
    let vec: Vec<_> = cli.iter()
        .map(|s| CString::new(s.as_bytes()).unwrap())
        .collect();
    let vec_obj: Vec<&CStr> = vec.iter().map(|c| c.as_c_str()).collect();
    println!("CString:{:?}", vec);
    println!("&CStr:{:?}", vec_obj);
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c440ea898abe2ed5573993923ee6b74f

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-01
    • 1970-01-01
    • 2021-11-30
    • 2020-01-09
    • 1970-01-01
    相关资源
    最近更新 更多