[英]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);
}
}
我將逐行(但不按順序)解釋問題所在以及如何解決。
首先,您說過要避免警告並避免發送無意義的變量。 我同意這些參數是不必要的。 為了避免在函數及其參數中添加變量,將在以下行中將生命周期參數添加到impl
和struct
定義中:
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.