简体   繁体   English

Rust `if let` 语句中的双重可变借用

[英]Double mutable borrow in Rust `if let` statement

Why does the following code coed in Rust yell a double mutable borrow error?为什么 Rust 中的以下代码会出现双重可变借用错误? I would expect the first scope to be the first block since the returned values can't outlive this block, and the else if won't be called if the first if returned Some(arr) .我希望第一个 scope 是第一个块,因为返回的值不能超过这个块,如果第一个if返回Some(arr) ,则不会调用else if

                if let Some(arr) = v.as_array_mut(){
                    ...

                } else if let Some(obj) = v.as_object_mut(){
                    ...
                } else {
                    ...
                }
    |
178 |                 if let Some(arr) = v.as_array_mut(){
    |                                    -------------------------- first mutable borrow occurs here
...
195 |                 } else if let Some(obj) = v.as_object_mut(){
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |                                           |
    |                                           second mutable borrow occurs here
    |                                           first borrow later used here

BTW, breaking each call to two calls, which provides an exact similar behavior obviously doesn't yell an error:顺便说一句,将每个调用中断为两个调用,这提供了完全相同的行为显然不会大喊错误:

                if v.is_array(){
                    
                    let arr = v.as_array_mut().unwrap();

                    ...

                } else if v.is_object(){
                    let obj = v.as_object_mut().unwrap();

                    ...
                } else {
                    ...
                }

This has to do with non-lexical lifetimes .这与非词汇生命周期有关。

Extend Rust's borrow system to support non-lexical lifetimes -- these are lifetimes that are based on the control-flow graph, rather than lexical scopes.扩展 Rust 的借用系统以支持非词法生命周期——这些生命周期基于控制流图,而不是词法范围。 The RFC describes in detail how to infer these new, more flexible regions, and also describes how to adjust our error messages. RFC 详细描述了如何推断这些新的、更灵活的区域,还描述了如何调整我们的错误消息。 The RFC also describes a few other extensions to the borrow checker, the total effect of which is to eliminate many common cases where small, function-local code modifications would be required to pass the borrow check. RFC 还描述了借用检查器的一些其他扩展,其总效果是消除了许多需要进行小的、函数本地代码修改才能通过借用检查的常见情况。 (The appendix describes some of the remaining borrow-checker limitations that are not addressed by this RFC.) (附录描述了本 RFC 未解决的一些剩余借用检查器限制。)

1.36 has NLL turned on for the 2015 edition. 1.36 为 2015 版启用了 NLL。 The 2018 edition enables them by default. 2018 版默认启用它们。

So in your case, I guess you are on a version not supporting NLL.因此,就您而言,我猜您使用的版本不支持 NLL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM