Rust 铁锈中的寿命

Rust 铁锈中的寿命,rust,lifetime,Rust,Lifetime,有时我发现自己想要编写可以通过以下两种方式调用的函数: // With a string literal: let lines = read_file_lines("data.txt"); // With a string pointer: let file_name = ~"data.txt"; let lines = read_file_lines(file_name); 我的第一个猜测是使用一个借用的指针(&str)作为参数类型,但当它不起作用时(它只允许我使用@str和~str),我

有时我发现自己想要编写可以通过以下两种方式调用的函数:

// With a string literal:
let lines = read_file_lines("data.txt");

// With a string pointer:
let file_name = ~"data.txt";
let lines = read_file_lines(file_name);
我的第一个猜测是使用一个借用的指针(
&str
)作为参数类型,但当它不起作用时(它只允许我使用
@str
~str
),我尝试了以下方法(通过复制Rust库),但确实起了作用

fn read_file_lines<'a>(path: &'a str) -> ~[~str] {
    let read_result = file_reader(~Path(path));
    match read_result {
        Ok(file) => file.read_lines(),
        Err(e) => fail!(fmt!("Error reading file: %?", e))
    }
}
fn读取文件\u行~[~str]{
让read_result=file_reader(~Path(Path));
匹配读取结果{
确定(文件)=>file.read_行(),
Err(e)=>fail!(fmt!(“读取文件时出错:%?”,e))
}
}
问题是我不明白我在做什么。根据我所能收集到的信息(主要来自编译器错误),我声明了一个没有限制的生存期,并用它来描述path参数(意味着任何生存期都可以作为参数传递)

因此:

  • 我的理解是否准确
  • 什么是一生?我在哪里可以更多地了解他们
  • 在上面的示例中,
    &str
    类型的参数与
    &a str
    类型的参数之间有什么区别
  • 当我这么做的时候,
    的自我是什么
(如果对答案有影响的话,我使用的是Rust 0.7)

更新2015-05-16:原始问题中的代码适用于旧版本的Rust,但概念保持不变。此答案已更新为使用现代Rust语法/库。(基本上将
~[]
更改为
Vec
~str
更改为
字符串
,并调整最后的代码示例。)

我的理解是否准确?
[…]
在上面的示例中,类型为&str的参数与类型为&a str的参数之间有什么区别

是的,像这样的一生基本上是“没有限制”的。生存期是将输出值与输入连接起来的一种方式,即
fn foo&'a T
表示
foo
返回一个与
T
具有相同生存期的指针,也就是说,它指向的数据在与
T
相同的时间长度内有效(严格来说,至少与
T
相同)。这基本上意味着返回值指向
t
指向的内存的某个部分

因此,像
fn-Vec
这样的函数非常类似于编写
{let x=1;return 2;}
。。。这是一个未使用的变量

Rust在写入
&str
时指定默认生存期,这与写入未使用的变量生存期完全相同。i、 e.
fn(路径:&str)->Vec
与带有
'a
s的版本没有区别。如果您需要强制执行全局指针(即特殊的
'static
生存期),或者如果您想要返回引用(例如
->&str
),则只在返回值有生存期时才可能返回,则只在这一情况下,才可以取消生存期(这必须是一个或多个输入的生存期,或者是静态的)

什么是一生?我在哪里可以学到更多关于他们的知识

生命周期是指针指向的数据保证存在的时间,例如,全局变量保证“永远”存在(因此它有一个特殊的生命周期
'static
)。查看它们的一种简洁方式是:生命周期将数据连接到其所有者所在的堆栈帧;一旦堆栈帧退出,所有者就超出范围,指向/进入该值/数据结构的任何指针都不再有效,而生命周期是编译器对此进行推理的一种方式。(在堆栈帧视图中,就好像
@
有一个与当前任务关联的特殊堆栈帧,而
static
有一个“全局”堆栈帧)

还有一个,和(注意,代码现在已经过时了,但概念仍然正确)是一个简洁的小演示,演示了如何使用生命周期来避免复制/分配(有一个强大的安全保证:没有悬空指针的可能性)

当我这么做的时候,
的自我是什么

实际上没有什么特别的,只是某些地方要求类型具有生存期(例如,在struct/enum定义和
impl
s中)和当前唯一被接受的名称是
'self
'static
'static
对于全局始终有效的指针,
'self
对于可以有任何生存期的对象。将(非
static
)生存期称为
self
以外的任何对象都是错误的


总而言之,我会这样写函数:

use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;

fn read_file_lines(path: &Path) -> Vec<String> {
    match File::open(path) {
        Ok(file) => {
            let read = BufReader::new(file);
            read.lines().map(|x| x.unwrap()).collect()
        }
        Err(e) => panic!("Error reading file: {}", e)
    }
}

fn main() {
   let lines = read_file_lines(Path::new("foo/bar.txt"));
   // do things with lines
}
使用std::fs::File;
使用std::io::prelude::*;
使用std::io::BufReader;
使用std::path::path;
fn读取文件行(路径:&路径)->Vec{
匹配文件::打开(路径){
确定(文件)=>{
让read=BufReader::new(文件);
read.lines().map(|x | x.unwrap()).collect()
}
Err(e)=>panic!(“读取文件时出错:{}”,e)
}
}
fn main(){
让行=读取文件行(路径::new(“foo/bar.txt”);
//用线做事
}

我对生命周期没有足够的信心来回答您的问题。但是,我可以告诉您
“data.txt”的类型
&'static str
,这是一个静态分配的字符串。谢谢!在我的示例中,您关于指定冗余生存期的说法似乎是正确的。我想我在0.6中需要它来使用
'static str
的方法,但在升级到0.7后没有重新测试。只需阅读教程:它(以及您的解释)很有帮助。再次感谢。我还有一大堆
impl@Daniel,没问题:)(是的,
impl
s是借用的指针需要有生存期的地方之一,也就是说,现在不能为&str
编写
impl-MyExtraFunction。)(还有,如果你还没有,通常会有几个人愿意帮忙。)@nalzok:从某种意义上说你是对的,但这相当微妙。实际价值指向