首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么泛型函数不需要生命周期?

为什么泛型函数不需要生命周期?
EN

Stack Overflow用户
提问于 2022-04-03 02:58:32
回答 2查看 207关注 0票数 6

这段代码不会编译,因为生锈需要增加一个生命周期。

代码语言:javascript
复制
fn firstNoLifetime(x: &str, y: &str) -> &str {
    return x;
}

因此,我们必须像下面这样显式地添加生存期:

代码语言:javascript
复制
fn first<'a>(x: &'a str, y: &'a str) -> &'a str {
    return x;
}

那么,我的问题是,这个没有生命周期的函数是如何编译的?

为什么泛型函数不需要生命周期,还有什么警告吗?

代码语言:javascript
复制
fn first_generic<A>(x: A, y: A) -> A {
    return x;
}

我的假设是,生存期注释可以帮助编译器和借用检查器确定生命周期违规的根本原因,但是在下面的代码中,铁锈能够在没有注释的情况下确定原因。我的假设是错的吗?如果是的话,生命期注释的目的是什么?

代码语言:javascript
复制
fn first_generic<A>(x: A, y: A) -> A {
    return x;
}

fn main() {
    let string1 = String::from("long string is long");
    let result: &str;
    {
        let string2 = String::from("xyz");
        result = first_generic(string1.as_str(), string2.as_str());
    }

    println!("The first string is: {}", result);
}

结果:

代码语言:javascript
复制
   |
10 |         result = first_generic(string1.as_str(), string2.as_str());
   |                                                  ^^^^^^^^^^^^^^^^ borrowed value does not live long enough
11 |     }
   |     - `string2` dropped here while still borrowed
12 | 
13 |     println!("The first string is: {}", result);
   |                                           ------ borrow later used here
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-04-03 03:33:27

生命是类型本身的一部分。

在您的第一个示例中,您要为所有的'ay和返回值指定相同的I.y。如果您接收单个值作为参考,您将不必通过终身说明符,对吗?

代码语言:javascript
复制
fn first(x: &str) -> &str {
    x
}

这是因为编译器可以自己推断出两者的生命周期。

回到你的问题,“为什么生命周期不是通用函数所必需的”,简短的回答是肯定的。只是不是你提供的例子。为什么?

在第二个示例中,您表示xy和返回值必须具有与它们都是A的相同类型。提醒生命周期是类型本身的一部分,这里只有一个生命周期发挥作用,所以编译器可以自己推断它。

我的假设是,生存期注释可以帮助编译器和借入检查器确定生命周期违规的根本原因,

是的,你的假设也是正确的。在这种情况下,生存期注释可以帮助编译器和借入检查器来确定生存期冲突的根本原因。

但是在下面的代码中,铁锈能够在没有注释的情况下确定原因。

正如上面提到的,这里只有一个生命周期,所以铁锈可以自己推断。然而,在某些旧版本的锈蚀编译器中,情况并非如此(我不记得确切的版本,但当时,我们也必须在一般情况下指定生存期注释)。

票数 1
EN

Stack Overflow用户

发布于 2022-04-03 04:45:39

当在函数签名中省略生命周期时,每个输入生命周期都会成为一个不同的匿名生命周期参数。因此,这是:

代码语言:javascript
复制
fn firstNoLifetime(x: &str, y: &str) -> &str {
    return x;
}

相当于:

代码语言:javascript
复制
fn firstNoLifetime<'a, 'b>(x: &'a str, y: &'b str) -> &'? str {
    return x;
}

但是,返回值的生存期是多少?在这里使用独特的生命周期是没有意义的,因为没有任何有用的引用能够满足这个生命周期。

根据寿命省略规则,当存在单个输入生存期时,返回值将使用该生存期。如果有多个输入生命周期,但其中一个是&self&mut self,则返回值将使用self的生存期。这些规则的原因是,我们不希望基于函数的实现来进行生命期推断,因为实现中的更改可能导致签名的更改,这通常是一个突破性的更改。

泛型函数之所以工作,是因为生存期参数是引用类型的一部分。当使用引用调用first_generic时,编译器必须找到与这两个参数兼容的单个类型(包括查找公共生存期),这与first的方式相同。我们在firstNoLifetime中获得的错误不能在first_generic中发生,因为firstNoLifetime的参数有不同的类型,而first_generic则不会发生错误,因为我们指定了这两个参数具有相同的A类型(不管A是什么)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71722661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档