Rust 在哈希映射中存储对向量项的引用时,绑定的有效期不够长
我对生锈还不熟悉,但仍在和借书人核对器搏斗,而且我的一生都是正确的 下面是我开始构建的一个简单结构-它存储命令行参数的集合,类似于东西(可以用Rust 在哈希映射中存储对向量项的引用时,绑定的有效期不够长,rust,lifetime,Rust,Lifetime,我对生锈还不熟悉,但仍在和借书人核对器搏斗,而且我的一生都是正确的 下面是我开始构建的一个简单结构-它存储命令行参数的集合,类似于东西(可以用--string或-c或两者表示): 我向每个散列映射传递一个引用(因此它们借用它),然后将选项直接传递给向量以将其移动到那里,这样选项就不会超出范围 似乎'a的范围和选项的范围对我来说应该是相同的-因为OptionMap是用生存期'a创建的,而T也受该生存期的约束,并且选项在函数末尾被移到选项中。我错过了什么?我觉得我一辈子都在与铁锈作斗争,好像有什么东
--string
或-c
或两者表示):
我向每个散列映射传递一个引用(因此它们借用它),然后将选项直接传递给向量以将其移动到那里,这样选项就不会超出范围
似乎'a
的范围和选项的范围对我来说应该是相同的-因为OptionMap
是用生存期'a
创建的,而T
也受该生存期的约束,并且选项
在函数末尾被移到选项中。我错过了什么?我觉得我一辈子都在与铁锈作斗争,好像有什么东西还没有给我带来惊喜
我向每个哈希映射传递一个引用(因此他们借用了它),然后
然后将选项直接传递给向量,将其移动到那里,以便
该选项没有超出范围
一旦有东西被借了,你就不能把它移到别处去
如果将元素放置到向量中并从中借用,则在借用结束之前无法对向量进行变异
换句话说,你目前的方法行不通
最简单的解决方案可能是将索引存储到哈希映射中的向量中
或者,也可以设计一个可以与短名称和长名称进行比较的奇特密钥,然后您可以将该选项直接存储在单个哈希映射中。我之所以说“可能”,是因为我不确定这目前是否可行。我想说,我知道《rust》中的docopt
等,但我自己写这本书是一个很好的练习,可以让你熟悉语言。我喜欢索引方法,这样可以更容易地复制它们,不需要借用。我会试一试这让我想到-我把东西放在vec中的唯一原因是它可以被OptionMap
结构所拥有-似乎应该有一个向量类型可以添加到,但在其他方面是不可变的,因此,添加到该向量中的值可以被借用,同时仍然能够将新元素推送到该向量上。一旦向量超出其容量,并且必须重新分配,这将导致无效引用。
struct OptionMap<'a, T: 'a> {
name: HashMap<String, &'a T>,
short_name: HashMap<char, &'a T>,
options: Vec<T>
}
impl<'a, T: 'a> OptionMap<'a, T> {
pub fn new() -> OptionMap<'a, T> {
OptionMap {
name: HashMap::new(),
short_name: HashMap::new(),
options: Vec::new()
}
}
pub fn register(&mut self, name: &OptionName, option: T) {
if name.name.is_some() {
self.name.insert(name.name.unwrap().to_owned(), &option);
}
if name.short_name.is_some() {
self.short_name.insert(name.short_name.unwrap(), &option);
}
self.options.push(option);
}
}
Compiling glam v0.1.0 (file:///Users/carson/Projects/glam)
src/options.rs:57:66: 57:72 error: `option` does not live long enough
src/options.rs:57 self.name.insert(name.name.unwrap().to_owned(), &option);
^~~~~~
src/options.rs:54:62: 66:6 note: reference must be valid for the lifetime 'a as defined on the block at 54:61...
src/options.rs:54 pub fn register(&mut self, name: &OptionName, option: T) {
src/options.rs:55 {
src/options.rs:56 if name.name.is_some() {
src/options.rs:57 self.name.insert(name.name.unwrap().to_owned(), &option);
src/options.rs:58 }
src/options.rs:59 }
...
src/options.rs:54:62: 66:6 note: ...but borrowed value is only valid for the scope of parameters for function at 54:61
src/options.rs:54 pub fn register(&mut self, name: &OptionName, option: T) {
src/options.rs:55 {
src/options.rs:56 if name.name.is_some() {
src/options.rs:57 self.name.insert(name.name.unwrap().to_owned(), &option);
src/options.rs:58 }
src/options.rs:59 }
...