2015-02-23 73 views
5

我试图教我一些铁锈,并已书面的东西,看起来像:如何将返回值的生命周期设置为我移入其中的变量的生命周期?

let args:Vec<String> = env::args().collect(); 
let parsed = parser::sys(args.as_slice()); 

...

pub fn sys<'a>(args:&'a [String]) -> Parsed<'a> { 
    parsed(args) 
} 

其中parsed是一个分析和负荷CONFIGS功能。

这工作正常。现在,我试图抽象掉显式调用env::args(),并隐藏在调用sys,所以我写的sys

pub fn sys<'a>() -> Parsed<'a> { 
    let args:Vec<String> = env::args().collect(); 
    parsed(args.as_slice()) 
} 

一个新的版本而与此失败:

error: `args` does not live long enough 
src/test.rs:66  parsed(args.as_slice()) 

我认为错误是因为编译器无法推断出我希望这个新创建的结构的生命周期是我想要将其移入的变量的生命周期。它是否正确?我将如何注解这个返回值的生命周期/修复此问题?

回答

3

我认为这个错误是因为没有办法让编译器推断我希望这个新创建的结构体的生命周期是我想要将它移入的变量的生命周期。

其实没有。

的错误是因为你试图创建引用到变量args这将不再是有效的,你从sys因为args返回后,一个局部变量,因此在sys末被丢弃。

如果您想使用引用,你可以提供sys&'a mut Vec<String>(空),填充在sys,并返回对它的引用:

pub fn sys<'a>(args: &'a mut Vec<String>) -> Parsed<'a> { 
    *args = env::args().collect(); 
    parsed(args.as_slice()) 
} 

这保证了args活得比的sys电话。这将在结果的整个生命周期内借用args

另一种解决方案是取消'a,只是简单地让Parsed拥有它的元素而不是引用它们;然而没有Parsed的定义,我不能建议如何最好地这样做。

+0

是否没有办法将参数“移出”sys,例如:像std:移动或复制elision。下面的工作,但我也分配给本地变量,但不知何故,我认为编译器知道如何将其移出: pub fn contents(source:&String) - > Vec { let mut reader = BufferedReader: :new(File :: open(&Path :: new(source))); reader.lines()。map(| l | l.unwrap())collect() } – sgldiv 2015-02-23 11:26:51

+0

@sgldiv'Reader :: lines'是一个'Iterator ',而不是'Iterator '。您返回一个'Vec ',它拥有所有返回的数据的完全所有权。没有什么东西可以借用返回值,编译器神奇地默默地移动。 – delnan 2015-02-23 11:43:06

+0

这是有道理的。谢谢! – sgldiv 2015-02-23 11:58:16