在Rust(版本1.x)中,我想在循环中使用集合的元素,例如下面的示例(它会记录它看到的字符并在发现重复的字符时执行某些操作),其中集合在函数内部定义并且仅由循环使用 .
fn do_something(word:&str) -> u32 {
let mut seen_chars = HashMap::new();
let mut answer : u32 = 0;
for (i,c) in word.chars().enumerate() {
let char_str = Box::new(c.to_string());
match seen_chars.get(&char_str) {
Some(&index) => {
answer = answer + index;
},
None => {seen_chars.insert(char_str,i);}
};
}
answer
}
为了在我的hashmap中存储对c的引用(我在循环之外声明了),我需要将c封装并在堆上分配 . 这感觉无穷无尽,我必须做错事 . 我想知道使用显式生命周期是否是更好的做事方式,下面是我最好的尝试,但我无法编译 .
fn do_something<'a>(word:&str) -> u32 {
let mut seen_chars = : &'a HashMap<&str,usize> = &HashMap::new();
let mut answer : u32 = 0;
for (i,c) in word.chars().enumerate() {
let char_str = &'a str = &c.to_string();
match seen_chars.get(&char_str) {
Some(&index) => {
answer = answer + index;
},
None => {seen_chars.insert(char_str,i);}
};
}
answer
}
当我尝试编译时,我得到“错误:借来的值不够长”,并指出“&HashMap :: new()”是问题所在 . 我可以使用生命周期规范来解决这个问题,或者我在这里做错了吗?
1 回答
我不认为你的任何一种方法都是最好的解决方案 . 您可以使用char本身作为HashMap的键,无需将其转换为String:
(我还必须更改
answer
的类型以使其编译,因为enumerate
给你usize
s . 或者,你可以在必要时将i
转换为u32
)如果由于某种原因,您想要使用字符串键而不是
char
,则必须使用自有字符串(即String
)而不是字符串切片(&str
) . 你会得到这样的东西:但我强烈怀疑第一个选项是你真正想要的 .