是否可以构建一个引用环境变量的 &str HashMap?

fre*_*eas 1 rust

我正在尝试制作环境变量的只读映射。

fn os_env_hashmap() -> HashMap<&'static str, &'static str> {
    let mut map = HashMap::new();
    use std::env;
    for (key,val) in env::vars_os() {
        let k = key.to_str();
        if k.is_none() { continue } 
        let v = val.to_str();
        if v.is_none() { continue }
        k.unwrap();
        //map.insert( k.unwrap(), v.unwrap() );
    }
    return map;
}
Run Code Online (Sandbox Code Playgroud)

如果没有关于 key、val、k 和 v 是本地的编译器错误,似乎无法取消对底部附近的“插入”行的注释。

也许可以通过使用 String 而不是 str 来修复编译器错误,但 str 似乎非常适合只读结果。

随意建议一个更惯用的方法来做到这一点。

tre*_*tcl 6

不幸的是,仅使用 Rust 标准库的工具并不简单。

如果env::vars_os()返回一个迭代器&'static OsStr而不是OsString,这将是微不足道的。不幸的是,并非所有平台都允许创建&OsStr环境变量的内容。特别是,在 Windows 上,本机编码是 UTF-16 但所需的编码OsStrWTF-8。出于这个原因,实在没有OsStr任何地方,你可能需要一个参考,直到您创建一个OsString由迭代env::vars_os()

正如问题评论中提到的,最简单的事情是返回owned Strings:

fn os_env_hashmap() -> HashMap<String, String> {
    let mut map = HashMap::new();
    use std::env;
    for (key, val) in env::vars_os() {
        // Use pattern bindings instead of testing .is_some() followed by .unwrap()
        if let (Ok(k), Ok(v)) = (key.into_string(), val.into_string()) {
            map.insert(k, v);
        }
    }
    return map;
}
Run Code Online (Sandbox Code Playgroud)

结果不是“只读”的,但它不是共享的,所以你不能通过改变它来导致数据竞争或其他奇怪的错误。

也可以看看