【问题标题】:Can I get a value from an immutable BTreeMap?我可以从不可变的 BTreeMap 中获取值吗?
【发布时间】:2020-12-01 19:43:10
【问题描述】:

以下两个代码块是等效的,但由于某种原因,我在第二个代码块上遇到了编译器错误。

我很难理解为什么 names 在一个版本中被借用,而不是在另一个版本中。

我试图弄清楚如何从不可变的BTreeMap 中读取数据,但似乎没有明确的方法。

工作正常:

let region_name: Option<String> = match subdivision.to_owned() {
    Some(division) => match division.names.unwrap().get("en") {
        Some(name) => Some(name.to_string()),
        _ => None,
    },
    _ => None,
};

不编译:

let region_name: Option<String> = subdivision
    .to_owned()
    .and_then(|division|division.names)
    .and_then(|names| names.get("en"))
    .and_then(|name| Some(name.to_string()));

编译器消息:

error[E0515]: cannot return value referencing function parameter `names`
  --> src/lib.rs:82:27
   |
82 |         .and_then(|names| names.get("en"))
   |                           -----^^^^^^^^^^
   |                           |
   |                           returns a value referencing data owned by the current function
   |                           `names` is borrowed here

subdivision 如下:

#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct Subdivision<'a> {
    pub geoname_id: Option<u32>,
    pub iso_code: Option<&'a str>,
    pub names: Option<BTreeMap<&'a str, &'a str>>,
}

【问题讨论】:

    标签: rust immutability borrow-checker borrowing


    【解决方案1】:
    .and_then(|names| names.get("en"))
    

    names 在函数(或闭包)的末尾被删除,但您试图返回 names.get("en"),它引用了 names (Option&lt;&amp;&amp;str&gt;) 中的值。

    .and_then(|data| data.get("en").map(|s| s.to_string()))
    

    此代码可能有效。

    【讨论】:

    • 我明白了...来自Iteratormap 方法采用闭包并创建一个新的Iterator。这就说得通了。谢谢!
    • 注意这里不是Iterator::map,而是Option::map,因为BTreeMap::get返回Option。然而,这个想法是一样的——“把这个函数应用到里面的所有东西上”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    相关资源
    最近更新 更多