我正在尝试对 HashMap 执行多次查找。在程序的主循环中,我的方法运行得很好。然而,一旦我尝试将逻辑移至函数中以隐藏一些混乱的实现细节(HashMap 键的区分大小写),我就会从编译器中收到一条错误消息,指出:
returns a value referencing data owned by the current function
,针对 (x86_instruction, x86_64_instruction)
。
程序主循环中的代码:
let raised_word = word.to_uppercase();
let x86_instruction =
names_to_instructions.get(&(Arch::X86, &*word)).map_or_else(
|| {
names_to_instructions
.get(&(Arch::X86, &raised_word))
},
|instr| Some(instr),
);
let x86_64_instruction =
names_to_instructions.get(&(Arch::X86_64, &*word)).map_or_else(
|| {
names_to_instructions
.get(&(Arch::X86_64, &raised_word))
},
|instr| Some(instr),
);
尝试进入一个函数:
pub fn search_for_instr<'a>(
word: &'a str,
map: &'a NameToInstructionMap<'a>
) -> (Option<&'a&'a Instruction>, Option<&'a&'a Instruction>) {
let raised_word = word.to_uppercase();
let x86_instruction =
map.get(&(Arch::X86, &*word)).map_or_else(
|| {
map
.get(&(Arch::X86, &raised_word))
},
|instr| Some(instr),
);
let x86_64_instruction =
map.get(&(Arch::X86_64, &*word)).map_or_else(
|| {
map
.get(&(Arch::X86_64, &raised_word))
},
|instr| Some(instr),
);
(x86_instruction, x86_64_instruction)
}
我不明白为什么 HashMap 查找的结果是通过
.get()
引用用于其查找的数据。有可能通过一些精心放置的 .clone()
来解决这个问题,但如果可能的话,我更喜欢更干净的解决方案。我还意识到我可以将 raised_word
作为字符串参数传递,而不是将其创建为局部变量,但这对我来说在抽象方面感觉相当泄漏。
这看起来像 Issue 80389“HashMap::get() 的输入(键)的生命周期与其输出(值)的生命周期纠缠在一起”:
HashMap::get
的签名是
fn get<Q>(&self, k: &Q) -> Option<&V>
所以
&V
需要 &self
和 &Q
的生命周期,也就是说它与密钥的生命周期相关,即使密钥仅在检索期间需要并且此后无关。遗憾的是,除了克隆 raised_word
之外,我认为没有其他解决办法。
请注意,您的代码比必要的复杂得多,
map_
的map_or_else
没有用,结果中的双重引用也没有用。此外,地图的生命周期及其值的生命周期应该非常不一样。