rust 从HashMap&lt;UniCase&lt;Cow &gt;,_&gt;中删除生存期问题< str>

c9qzyr3d  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(109)

UniCase没有实现Borrow,这意味着如果不分配String,就不能用UniCase键索引map。建议的解决方法是使用HashMap<UniCase<Cow<str>>, _>。不幸的是,它并不总是编译;

use std::borrow::Cow;
use std::collections::HashMap;
use std::io::Result;

use unicase::UniCase;

fn rm_reader_keys<R: BufRead>(
    reader: R, dict: &mut HashMap<UniCase<Cow<str>>, String>
) -> Result<()> {
    for ln in reader.lines() {
        let line: String = ln?;
        if let Some((key, _)) = line.rsplit_once(' ') {
            dict.remove(&UniCase::unicode(Cow::Borrowed(key)));
        }
    }
    Ok(())
}

产生

error[E0597]: `line` does not live long enough
  --> src/main.rs:44:33
   |
40 |     reader: R, dict: &mut HashMap<UniCase<Cow<str>>, String>
   |                ---- has type `&mut HashMap<UniCase<Cow<'1, str>>, std::string::String>`
...
43 |         let line: String = ln?;
   |             ---- binding `line` declared here
44 |         if let Some((key, _)) = line.rsplit_once(' ') {
   |                                 ^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
45 |             dict.remove(&UniCase::unicode(Cow::Borrowed(key)));
   |             -------------------------------------------------- argument requires that `line` is borrowed for `'1`
46 |         }
47 |     }
   |     - `line` dropped here while still borrowed

有办法解决吗?

i1icjdpr

i1icjdpr1#

我不相信这是可能的问题是类型必须完全相同,所以我们需要与函数的参数相同的生存期。但它是通用的,我们没有办法让字符串存活那么长时间。
但是,您可以直接使用hashbrown。它具有Equivalent特征,比Borrow更通用:

use hashbrown::HashMap;

#[derive(Hash)]
struct UniCaseStrWrapper<'a>(UniCase<&'a str>);
impl hashbrown::Equivalent<UniCase<String>> for UniCaseStrWrapper<'_> {
    fn equivalent(&self, key: &UniCase<String>) -> bool {
        self.0 == *key
    }
}

fn rm_reader_keys<R: BufRead>(
    reader: R, dict: &mut HashMap<UniCase<String>, String>
) -> Result<()> {
    for ln in reader.lines() {
        let line: String = ln?;
        if let Some((key, _)) = line.rsplit_once(' ') {
            dict.remove(&UniCaseStrWrapper(UniCase::unicode(key)));
        }
    }
    Ok(())
}

相关问题