2014-01-20 19 views
2

我有一个关于Rust编程语言中的可变寿命的问题。锈的生命期和调用成员函数

createTest函数创建并返回r值引用。当它返回一个引用时,testValue被销毁。但test.print()不会导致崩溃。为什么?

(被称为静态函数测试::打印功能?)

代码

struct Test;               
impl Drop for Test {              
    fn drop (&mut self) {              
    println("Dropped.");             
    }                   
}                   

impl Test {                 
    fn print(&self) { println!("Print!"); }         
}                   

fn createTest() -> &Test {             
    let testValue = &Test;             
    return testValue;               
}                   

fn main() {                 
    let test = createTest();            
    test.print();                
    println("Test");               
} 

结果

Dropped. 
Print! 
Test 

回答

3

代码编译的原因是因为使用了单元结构(即没有字段)的,基本上等同于:

struct Test; 

static TestStatic: Test = Test; 

fn createTest() -> &Test { 
     &TestStatic 
} 

这样一来,&TestStatic表达具有类型&'static Test每个有效期是'static的子寿命,包括-> &Test的隐式匿名寿命,因此您可以返回'static

此行为是由两个错误覆盖:


这就是说,它是非常奇怪,Drop运行这样的,所以谢谢备案11681

1

这看起来像我的错误。

struct Test { 
    x: int 
} 

impl Drop for Test { 
    fn drop (&mut self) { 
    println("Dropped."); 
    } 
} 

impl Test { 
    fn print(&self) { println!("Print: {}", self.x); } 
} 

fn createTest() -> &Test { 
    let testValue = &Test{ x: 10 }; 
    testValue 
} 

fn main() { 
    let test = createTest(); 
    test.print(); 
    println("Test"); 
} 

错误消息:你的榜样的简单延伸不绝然错误消息编译

main.rs:16:19: 16:24 error: borrowed value does not live long enough 
main.rs:16 let testValue = &Test{ x: 10 }; 
          ^~~~~ 
main.rs:15:26: 18:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 15:25... 
main.rs:15 fn createTest() -> &Test { 
main.rs:16 let testValue = &Test{ x: 10 }; 
main.rs:17 testValue 
main.rs:18 } 
main.rs:15:26: 18:2 note: ...but borrowed value is only valid for the block at 15:25 
main.rs:15 fn createTest() -> &Test { 
main.rs:16 let testValue = &Test{ x: 10 }; 
main.rs:17 testValue 
main.rs:18 } 

顺便说一句,你不必写return当你想从返回的东西函数,除非它是一个早期返回(例如从循环内部)。在最后的声明中,请留下分号。