Rust 当输入非常清楚时,为什么借用检查器需要输出生命周期标记?

Rust 当输入非常清楚时,为什么借用检查器需要输出生命周期标记?,rust,lifetime,borrow-checker,borrowing,Rust,Lifetime,Borrow Checker,Borrowing,为什么借用检查器会对下面代码中的生命周期感到困惑 fn main() { let ss = "abc"; // lets say 'a scope let tt = "def"; // lets say 'b scope let result = func(ss, tt); } fn func(s: &str, t: &str) -> &str { t } |fn funcs:&str,t:&str->&str{ |^预期

为什么借用检查器会对下面代码中的生命周期感到困惑

fn main() {
    let ss = "abc"; // lets say 'a scope
    let tt = "def"; // lets say 'b scope
    let result = func(ss, tt);
}    

fn func(s: &str, t: &str) -> &str {
    t
}
|fn funcs:&str,t:&str->&str{ |^预期寿命参数 | =帮助:此函数的返回类型包含借用值,但签名没有说明它是从's'还是't'借用的` 为什么这段代码中出现了什么问题?我是否遗漏了一些非常重要的边缘情况

但当我用生命时间标记对它们进行注释时,它就起作用了

fn func<'a>(s: &'a str, t: &'a str) -> &'a str {
    t
}

我读到每个变量绑定都会创建一个隐式作用域,那么为什么两个输入变量都有相同的作用域。如果我在工作,请纠正我。在函数调用“func”堆栈中,s会先被推,然后是t,因此s和t有不同的生存期。首先是t被删除,然后是s。

您还没有告诉编译器返回值是否会被删除R来自s、t、两者或两者均不来自:

fn来自&'a str,t:&'b str->&'a str{ //可以缩写为:fn from_s&'a str s } fn来自&'a str,t:&'b str->&'b str{ //可以缩写为:fn from_t&'a str T } fn来自两个&'static str{ //可以缩写为:fn funcs:&str,t:&str->&'static str 福 } 如果你没有写“static”,编译器可以假设最后一个不是你想要的。但是你仍然需要在前三个之间消除歧义

<> P>看看为什么差别会很重要,考虑一个像

这样的呼叫者 fn干线{ 设s=String::froms; 让r; { 设t=String::fromt; r=来自美国科学与技术部; //t超出范围 } println!{},r; }
如果编译器允许您从\u t而不是从\u s调用,则您将打印一个已被释放的字符串。

您没有告诉编译器返回值是否可以从s、从t、从两者或两者中借用:

fn来自&'a str,t:&'b str->&'a str{ //可以缩写为:fn from_s&'a str s } fn来自&'a str,t:&'b str->&'b str{ //可以缩写为:fn from_t&'a str T } fn来自两个&'static str{ //可以缩写为:fn funcs:&str,t:&str->&'static str 福 } 如果你没有写“static”,编译器可以假设最后一个不是你想要的。但是你仍然需要在前三个之间消除歧义

<> P>看看为什么差别会很重要,考虑一个像

这样的呼叫者 fn干线{ 设s=String::froms; 让r; { 设t=String::fromt; r=来自美国科学与技术部; //t超出范围 } println!{},r; }
如果编译器允许您从t而不是从s调用,您将打印一个已经释放的字符串。

如果我理解正确,问题是为什么两个参数可能具有相同的生存期?简短的回答是,生存期注释不是具体的值,而是边界-它声明该值必须存在不超过/不低于此生


当您像前面提到的那样编写代码时:fn func如果我理解正确,问题是为什么两个参数可能具有相同的生存期?简短的回答是,生存期注释不是具体的值,而是边界-它声明此值的生存期不得超过/少于此生存期


当您像所讨论的那样编写代码时:fn func您的输出有三个不同的生命周期“a”、“b”和“c”。编译器如何知道哪一个生命周期取决于哪个生命周期?:/因此编译器对此不是很清楚。您的可能副本有三个不同的生命周期“a”、“b”和“c”。编译器如何知道ich one取决于哪一个?:/因此编译器对此不是很清楚。可能会重复wouldn函数返回的事实不足以知道生存期吗?@coredump函数的类型应该封装所有需要知道的关于如何调用和不能调用的内容。如果您必须查看实现内部,以请看如何调用它,然后实现成为公共接口的一部分;对实现的每一个更改都会成为一个潜在的向后不兼容的更改。并且无法再指定具有多个潜在实现的特征。基本上,这是不好的。谢谢,这是有意义的eturns不足以知道生命周期?@coredump函数的类型应该封装所有需要知道的关于如何调用它和如何调用它的信息。如果您必须查看实现内部以了解如何调用它,那么实现将成为公共接口的一部分;对实现的每一次更改都将成为潜在的向后不兼容的变化。并且,具有多个潜在实现的特征将不再可能被指定。基本上,这将是不好的。谢谢,这是有意义的
fn main() {
    let ss = "abc";
    let mut result = "";
    {
        let tt = "def".to_string();
        result = func(ss, &tt);
    }
    println!("{}", result);
}    

fn func<'a>(s: &'a str, t: &'a str) -> &'a str {
    s
}
fn func<'a, 'b>(s: &'a str, t: &'b str) -> &'a str {
    s
}