我对Rust非常陌生,为了更熟悉我开始编写一些ToDo程序的语言。
我已经制作了一个与任务相对应的结构:
struct Task {
id: int,
title: &'static str
}
我试图实现一些方法直接将格式化的行写入文件中:
impl Task {
fn to_string (&self) -> String {
let line = self.id.to_string() + "\t" + self.title;
line
}
fn to_str (&self) -> &str {
let line = self.to_string();
let formatted_str : &str = line.as_slice();
formatted_str
}
}
我收到一条错误,上面写着' line'活得不够久。我已经尝试添加生命周期信息,如下所示:http://rustbyexample.com/lifetime/fn.html但我又遇到了同样的错误。
这种情况有解决方案吗?我是Rust的新手,所以我可能错过了一些东西。
感谢您的帮助!
答案 0 :(得分:4)
这基本上是不可能的。如果你返回某个东西的引用,那么某些内容必须存储在某个地方。忽略任务本地存储和静态,这意味着只需&self
的方法就必须将其存储在self
中。
您不能返回对您返回的方法所拥有的内容的引用,因为当您返回引用它时,它会超出范围并被销毁。
如果他们需要字符串切片而不是拥有的字符串,请让调用者自己调用self.to_string().as_slice()
。
顺便说一下,为了获得最佳效果,您应该实施std::fmt::Show
;
use std::fmt;
impl fmt::Show for Task {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}\t{}", self.id, self.title)
}
}
这会自动为您提供.to_string()
method,您可以直接在Task
中使用format!("{}", task)
,依此类推。
答案 1 :(得分:2)
如果我们查看rust documentation for str
,我们会发现一些有见地的摘录。
& str是借用的字符串类型。这种类型的字符串只能从其他字符串创建,除非它是静态字符串
和
字符串的实际表示具有与向量的直接映射:& str与& [u8]相同。
这意味着非静态&str
被表示为指向u8
的向量所拥有的数据的指针(即String
)。但是,&str
本身并不拥有u8
。
line
,在上面的代码中,是to_str
函数中的局部变量。这意味着当to_str
返回时,line
超出范围,并且它会破坏它拥有的数据:一堆u8
&#39}。 formatted_str
正在借用line
拥有的数据。因此,您无法返回formatted_str
,因为当to_str
返回时,它借用的数据的生命周期结束。您可以在a simplified version of the code you provided中找到更清楚的内容。
我自己没有足够的经验来提供解决问题的方法,但希望这可以解释错误。