Rust 是";这表示代码中潜在的未定义行为”;使用匹配arm保护时出错编译器中的错误?

Rust 是";这表示代码中潜在的未定义行为”;使用匹配arm保护时出错编译器中的错误?,rust,Rust,我的代码中有一个匹配表达式存在问题,当包含一个卫兵时会发出警告。我相信这个警告与借用检查器使用的非词汇生存期有关。My函数要么返回对集合中某个项的可变引用,要么返回整个集合的克隆 #[派生(调试、克隆)] 枚举值{ Int(i32), 名单(Vec), } #[导出(调试)] 结构错误(&'static str,Value); fn main(){ 让mut value=value::List(vec[ 值::Int(1), 值::Int(2), 值::Int(34), 值::Int(12),

我的代码中有一个匹配表达式存在问题,当包含一个卫兵时会发出警告。我相信这个警告与借用检查器使用的非词汇生存期有关。My函数要么返回对集合中某个项的可变引用,要么返回整个集合的克隆

#[派生(调试、克隆)]
枚举值{
Int(i32),
名单(Vec),
}
#[导出(调试)]
结构错误(&'static str,Value);
fn main(){
让mut value=value::List(vec[
值::Int(1),
值::Int(2),
值::Int(34),
值::Int(12),
]);
设y=索引列表(&mut值,2);
设u=dbg!(y);
}
fn index_list Result(值:&'a mut value,idx:usize)->结果正常(&mut list[idx]),
|---------返回此值需要为“%a”借用“value.0”`
|                     |
|可变借用发生在这里
25 | Value::List()=>Err(错误(“索引超出范围”,Value.clone()),
|^^^^^此处发生不可变借用
|
=警告:此错误已降级为警告,以便与以前的版本向后兼容
=警告:这表示代码中潜在的未定义行为,此警告将来将成为硬错误
警告[E0502]:无法将“*value”作为不可变项借用,因为它也是作为可变项借用的
-->src/main.rs:26:46
|
22 | fn索引列表结果正常(&mut list[idx]),
|---------返回此值需要为“%a”借用“value.0”`
|                     |
|可变借用发生在这里
25 | Value::List()=>Err(错误(“索引超出范围”,Value.clone()),
26 |=>Err(错误(“尝试索引int”,value.clone()),
|^^^^^此处发生不可变借用
|
=警告:此错误已降级为警告,以便与以前的版本向后兼容
=警告:这表示代码中潜在的未定义行为,此警告将来将成为硬错误

我不明白为什么
Err(value.clone())
行要求
Ok(&mut…)
borrow仍然处于活动状态,因为它们是互斥的,并且都会导致函数返回。如果我拆下第一支比赛手臂上的防护装置,这个警告就会消失,但我需要那个防护装置在那里。这是NLL系统中的错误吗?我从来没有和老借债人有过这样的问题。如何改进此操作?

此错误在我看来似乎是借用检查器的一个限制,类似于。我不明白这怎么会导致一个安全漏洞,我相信代码是安全的

使用
if
语句at而不是
match
时,可以避免警告,代码也会变得更可读:

fn bar<'a>(
    map: &'a mut HashMap<String, Vec<i32>>,
    name: &str,
    idx: usize,
) -> Result<&'a mut i32, Vec<i32>> {
    let value = map.get_mut(name).unwrap();
    if idx < value.len() {
        Ok(&mut value[idx])
    } else {
        Err(value.clone())
    }
}

fn有关此警告的一些讨论,请参阅条形图结果。显然,Borrock允许这样做是因为在某些情况下可能导致安全问题的健全性缺陷,但这是我的全部想法。这适用于我这里的简单示例,但在我的实际代码中,匹配是必需的,因为我在枚举上匹配。我编辑了问题中的示例,使其更接近实际代码,我不知道如何使用if表达式。