【问题标题】:Rust lang lifetime mismatch for HashMap with str key带有 str 键的 HashMap 的 Rust lang 生命周期不匹配
【发布时间】:2021-07-06 02:24:10
【问题描述】:

我正在尝试实现一个现有的 C++ 算法,该算法在 Rust 中有效,以了解生命周期是如何工作的。我们应该在下面使用什么模式...作为背景,这个算法试图找到最长回文子序列的长度。

use std::cmp::{max, min};
use std::collections::HashMap;
use std::str;

fn main() {
    let mut m = HashMap::new();
    println!(
        "Longest palin size: {}",
        longest_palin_substring("abdbca".as_bytes(), &mut m)
    );
}
    
    
    pub fn longest_palin_substring(is_palin: &[u8], map: &mut HashMap<&str, usize>) -> usize {
    println!("current string : {}", str::from_utf8(is_palin).unwrap());
    if is_palin.len() == 0 || is_palin.len() == 1 {
        return is_palin.len();
    }

    if let Some(len) = map.get(str::from_utf8(is_palin).unwrap()) {
        *len
    } else {
        let c1 = if is_palin[0] == is_palin[is_palin.len() - 1] {
            let r = longest_palin_substring(&is_palin[1..is_palin.len() - 1], map);
            if r == is_palin.len() - 2 {
                2 + r
            } else {
                0
            }
        } else {
            0
        };

        let c2 = longest_palin_substring(&is_palin[1..], map);
        let c3 = longest_palin_substring(&is_palin[..is_palin.len() - 1], map);

        let c = max(c1, max(c2, c3));
        map.insert(str::from_utf8(is_palin).unwrap(), c);
        c
    }
}

error[E0623]: lifetime mismatch
  --> src/main.rs:38:20
   |
14 |     pub fn longest_palin_substring(is_palin: &[u8], map: &mut HashMap<&str, usize>) -> usize {
   |                                              -----                    ----
   |                                              |
   |                                              these two types are declared with different lifetimes...
...
38 |         map.insert(str::from_utf8(is_palin).unwrap(), c);
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...but data from `is_palin` flows into `map` here

error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0623`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

我尝试将 &amp;'a 生命周期添加到所有引用中,但随后它抱怨多次发生可变借用。

 pub fn longest_palin_substring<'a>(                                                                                                                 
     is_palin: &'a [u8],                                                                                                                             
     map: &'a mut HashMap<&'a str, usize>,                                                                                                           
 ) -> usize {                                                                                                                                        

错误:

error[E0499]: cannot borrow `*map` as mutable more than once at a time

我的问题如下:

  • 首先,很明显,我应该如何着手修复这个编译错误
  • 用于记忆一些状态的模式会导致递归实现,例如动态编程。

任何可以让我了解更多有关 rust 模式的指针将不胜感激。

谢谢。

【问题讨论】:

    标签: rust lifetime borrow-checker


    【解决方案1】:

    你已经接近了。首先,hashmap 的生命周期将不同于其键类型的生命周期。

    编译错误可以这样修复:

    pub fn longest_palin_substring<'a>(is_palin: &'a [u8], map: &mut HashMap<&'a str, usize>) -> usize {
    

    作为一般规则,如果您不存储传递给函数的引用,则不需要对该类型进行任何生命周期注释,编译器使用函数签名来确定如何使用引用而不检查函数的内容.

    其次,为了记忆事物,我会使用一些内部可变性原语。如果算法是单线程的,那么 CellRefCell 可以,如果不是,Mutex 将允许你改变内部状态。

    如果事情只需要记住一次,你可能会对once_cell 感兴趣(它仍然只在夜间使用,但马厩中有一个 crate usabe)。

    【讨论】:

      猜你喜欢
      • 2013-07-03
      • 2021-10-27
      • 2018-03-19
      • 1970-01-01
      • 2015-09-24
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多