简体   繁体   中英

Rust lifetime and calling member function

I have a question about lifetime of varable in Rust programming language.

createTest function creates and returns r-value reference. and when it returns a reference, testValue is destroyed. But test.print() doesn't lead to crash. Why?

(Is Test::print function called as static function?)

Code

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");                                                         
}

Result

Dropped.
Print!
Test

The reason the code compiles is because the use of a unit struct (ie no fields), is basically equivalent to:

 struct Test;

 static TestStatic: Test = Test;

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

And so the &TestStatic expression has type &'static Test . Every lifetime is a sub-lifetime of 'static , including the implicit anonymous one for the -> &Test , so you're allowed to return a 'static in it's place.

This behaviour is covered by two bugs:


That said, it is very strange that Drop runs like that, so thank you for filing 11681 .

This looks like a bug to me. A simple extension of your example does not compile with absolutely natural error message:

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");
}

Error message:

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 }

BTW, you don't have to write return when you want to return something from a function unless it is an early return (eg from inside a loop). Just leave out semicolon at the last statement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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