簡體   English   中英

函數調用是否在rust或僅在變量中存在生命期?

[英]Do function calls have a lifetime in rust, or only variables?

編輯:這個問題顯然太復雜了。 這是一個更簡單的示例,解釋了我要問的問題:

#[feature(macro_rules)];    
macro_rules! trace(
  ($($arg:tt)*) => (
    { let x = ::std::io::stdout().write_line(format_args!(::std::fmt::format, $($arg)*)); println!("{}", x); }
  );
)

#[deriving(Show)]
struct Foo<T> {
  data: ~T
}

impl<T> Foo<T> {

  // Notice how the 'pontless_marker' variable is passed into this function for
  // no reason other than that it allows us to copy the lifetime scope of the
  // 'marker' variable in the test below, so the lifetime of the returned pointer
  // is valid for that block.
  fn returns_to_scope_with_marker<'a>(&'a self, pointless_marker:&'a int) -> &'a ~T {
    return &self.data;
  }

  // This doesn't work, but it should. You should be able to invoke this function
  // as something like: let marked = bar.returns_to_scope::<LIFETIME???>();
  /*
  fn returns_to_scope<'a>(& self) -> &'a ~T {
    return &self.data;
  }
  */
}

#[test]
fn test_lifetime_return_scope() {
  let bar = Foo { data: ~Foo { data: ~10 } };
  {
    let marker = 10;
    let marked = bar.returns_to_scope_with_marker(&marker);
    trace!("{:?}", marked);
  }
}

請參閱上面示例中的“ pointless_marker”。

這就是我要避免的。 如果該函數也被鍵入blah <'a>,我覺得我應該能夠使用x.blah :: << something here here>()顯式調用它。

這是完全不可能的嗎?

好的,下面的代碼有望解決您的問題:

#[feature(macro_rules)];    
//Macro rules is unchanged

#[deriving(Show)]
struct Foo<'a, T> {
  data: &'a T
}

impl<'a, T> Foo<'a, T> {

  fn returns_to_scope(&'a self) -> &'a T {
    self.data
  }
}

fn main() {
  let bar = Foo { data: &Foo { data: &10 } };
  {
    let marked = bar.returns_to_scope();
    trace!("{:?}", marked);
  }
}

我將逐行(但不按順序)解釋問題所在以及如何解決。

首先,您說過要避免警告並避免發送無意義的變量。 我同意這些參數是不必要的。 為了避免在函數及其參數中添加變量,將在以下行中將生命周期參數添加到implstruct定義中:

 struct Foo<'a, T> 
 ...
 impl<'a, T> Foo<'a, T> 
 // note: impl<'a,T> is mandatory, because we can say <'a, int> for example
 //       which is not what we want 

'a是生命周期參數,它充當另一個通用類型(即T )。

*如果我們有'a生命周期,我們有點需要將它綁定到某件事上……一旦在稍后的文本中修復了fn returns_to_scope我們將返回此部分,但是很明顯,數據將獲得生命周期,因為-只是Foo結構中的值,並且它從需要類似於&'a T的函數中返回。

現在,我們可以更好地看一下fn returns_to_scope函數。 如果您查看原始功能,您幾乎會正確。

 fn returns_to_scope<'a>(& self) -> &'a ~T {
   return &self.data;
 }

讓我感到不對的第一件事是您有一個&~指針( &'a ~T )。 為什么? 您知道這是指向在堆上分配的指針的堆棧指針嗎? 除非您正在做一些指向雜技的指針,否則它並不是真正有用的,但是我認為這是一個錯誤。 如果情況不好,您可以隨時輸入~T value並借用它。

因此,您希望自己的returns_to_scope以某種方式返回self.data字段,如果您要返回屬於結構Foo的字段,我認為使用與該字段所屬的結構Foo相同的生存期更為明智; 所以我將描述更改為:

fn returns_to_scope(&self) -> &'a T

我省略了<'a>泛型參數,因為我不需要在'a一生中將其泛化, 'a一生是該結構的一部分,我們可以通過借用該結構免費獲得它。 但是我忘了說&self生命周期,因此編譯器會抱怨,而我只是改變&self來注明'a生命周期”。

fn returns_to_scope(&'a self) -> &'a T

為了畫龍點睛,因為Rust允許通過省略而返回場; 我可以寫:

fn returns_to_scope(&'a self) -> &'a T {
   self.data
}

而不是return self.data;

現在我們看到struct的領域是'a一生的自然選擇

data: &'a T

被添加到結構Foo中,並且所有片段現在都就位。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM