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
- 当我这么做的时候,
的自我是什么
~[]
更改为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:从某种意义上说你是对的,但这相当微妙。实际价值指向