生 rust 问题:借用时删除临时值[重复]

dgtucam1  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(133)
    • 此问题在此处已有答案**:

Why can I return a reference to a local literal but not a variable?(1个答案)
why does rust allow a local struct reference had static lifetime? [duplicate](1个答案)
2天前关闭。
我有下面代码,

enum List<'a> {
        Cons(i32, Box<&'a List<'a>>),
        Nil,
    };
    let list= Cons(10, Box::new(&Nil));
    let lista = Cons(5, Box::new(&Cons(10, Box::new(&Nil))));
    match lista {
        Cons(x,_) => println!("{}",x),
        Nil => ()
    }

运行代码后,编译器会显示

21 |     let lista = Cons(5, Box::new(&Cons(10, Box::new(&Nil))));
   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^  - temporary value is freed at the end of this statement 
   |                                   |
   |                                   creates a temporary which is freed while still in use

我可以理解'cons(10,box::new(& Nil))'是免费的,所以它出错了。但是当我在匹配后用lista替换list时,例如:

match list {
        Cons(x,_) => println!("{}",x),
        Nil => ()
    }

我认为Nil也是一个临时值,在语句结束时丢弃,但它运行良好,list和lista有什么区别?

qnzebej0

qnzebej01#

这是因为rvaue static promotion。所有常量值的枚举变量都是constexpr,因此被提升为'static生存期。
例如:

enum TestEnum {
    Dynamic(String),
    NoValue,
    ConstStr(&'static str)
}
fn main () {
    use TestEnum::*;
    println!("NoValue:   {:?}", &NoValue as *const TestEnum);
    println!("NoValue:   {:?}", &NoValue as *const TestEnum);
    println!("ConstStr:  {:?}", &ConstStr("const-str") as *const TestEnum);
    println!("ConstStr:  {:?}", &ConstStr("const-str") as *const TestEnum);
    println!("Dynamic:   {:?}", &Dynamic(String::from("dynamic")) as *const TestEnum);
    println!("Dynamic:   {:?}", &Dynamic(String::from("dynamic")) as *const TestEnum);
}

产出:

NoValue:   0x7ff6a92cf380
NoValue:   0x7ff6a92cf380
ConstStr:  0x7ff6a92cf3e8
ConstStr:  0x7ff6a92cf3e8
Dynamic:   0xd56df7f578
Dynamic:   0xd56df7f5f8

只有Dynamic变量在创建时存储在新地址中,您也可以看到它具有显式的生存期:

// Compiles fine
let static_vaue : &'static TestEnum = &ConstStr("const-str"); 

// Does not compile
let dynamic_value : &'static TestEnum = &Dynamic(String::from("const-str"));

因此,代码在使用Nil时可以正常工作的原因是,引用的Nil值不会在语句之后被删除,因为它位于'static内存中,所以永远不会被删除。

相关问题