在Rust book (https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html)中,此代码用作示例(转译):
fn main() {
let string1 = String::from("long string is long");
{
let string2 = String::from("xyz");
let result = longest(string1.as_str(), string2.as_str()); // line 5
println!("The longest string is {}", result); // line 6
}
}
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
if x.len() > y.len() { x } else { y }
}我搞不懂为什么这段代码会编译。
关于longest函数,书中说,“泛型生命周期'a将获得等于x和y的生命周期中较小的生命周期的具体生命周期。”
这本书随后谈到,似乎string1.as_str()和string2.as_str()的寿命分别与string1和string2一样长。但他们为什么要这么做呢?这两个引用没有在第5行之后使用,而在第6行,它们应该是死的。当result不再有效时,为什么第6行没有出现使用结果的错误?
有人可能会说,result的存在以某种方式延长了输入生存期,但这不会与“输出生存期是输入生存期的交集”的概念相矛盾吗?
我哪里搞错了?
发布于 2021-01-30 12:48:27
,但他们为什么要这样做呢?这两个引用没有在第5行之后使用,而在第6行,它们应该是死的。
但他们还没死。事实上,其中一个肯定是在result中,并且在第6行使用。引用可以持续到当前表达式的末尾(通常,但不总是,直到分号),最多只要它所指向的事物继续存在。longest输出中的生命周期参数要求只要result在作用域中,它就会一直存在。值得注意的是,result的作用域并不比string1或string2的作用域大,因此不存在问题。如果我们试图将longest的结果赋给一个比string2存活时间更长的变量,那么我们就会遇到问题。例如,这不会编译。
fn main() {
let string1 = String::from("long string is long");
let mut result = "";
{
let string2 = String::from("xyz");
result = longest(string1.as_str(), string2.as_str());
}
println!("The longest string is {}", result);
}因为这将需要result比string2更持久,这是一个问题。
发布于 2021-01-30 23:27:53
在我看来,这种混淆似乎源于&'a str类型。'a是引用所引用的数据的生命周期,即该数据的有效区域。它不是参考变量本身有效的区域。
所以..。
string1.as_str()返回一个&'s1 str,其中's1是string1的生命周期。
string2.as_str()返回一个&'s2 str,其中's2是string2的生命周期。
longest必须从两个参数lifetime 'a和's2推断出单个通用生存期's1。它通过选择共同的重叠,较短的生命周期's2来做到这一点。这是子类型的一种形式:对于较长生命周期有效的引用可以透明地用作对较短生命周期有效的引用。
所以result是一个&'s2 str。
第6行引用&'s2 str类型的result,其中's2是string2的生存期。引用名称本身是可用的,引用数据在string2,'s2的生命周期内是有效的,我们仍然在其中。
string1.as_str()和string2.as_str()的寿命分别与string1和string2一样长
这是一种松散的措辞。它们是引用,它们不会持续超过第5行,但它们的生存期分别等于string1和string2的生存期。这意味着他们所指的数据至少可以存活那么长时间。
为什么在
result不再运行时,第6行没有出现错误?
result的类型为&'s2 str,因此它是有效的。它是第5行longest的两个(临时)引用之一的副本。名称result在第6行有效,它指向的数据保证与仍然有效的's2一样有效。因此,没有错误。
可以说,result的存在以某种方式延长了输入的生命周期
没有这样的扩展。这些临时表不存在于第5行之后,但其中之一被复制到result中,生存期不是临时生存期(输入引用&'a str生存期)的长度,而是引用数据的生存期。
https://stackoverflow.com/questions/65964669
复制相似问题