< 返回版块

berners 发表于 2023-03-13 13:04

Tags:生命周期,租借权

我在看教程的时候看到生命周期,然后回看前面的教程: When I read the tutorial, I see the Lifetime chapter, and then look back at the previous chapter .There is one of that sample code:

fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

这里的calculate_length引用和usize为什么可以不要求以生命周期'a的形式去声明?而且这里也不会报错。 Why can calculate_length and usize not be declared in the form of lifetime 'a ? And there will be no error here. 我看生命周期的教程时都要写成类似于这样: When I read the lifetime tutorial, I should write something like this:

fn longer<'a>(s1: &'a str, s2: &'a str) -> &'a str {
    if s2.len() > s1.len() {
        s2
    } else {
        s1
    }
}

有人说上面那个参数是1个,下面那个参数是2个,所以上面不会报错,然后我试了一下上面改成2个参数,一样没问题:

fn main() {
    let s1 = String::from("hello");
    let s2 = String::from("hello");

    let len = calculate_length(&s1,&s2);

    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String,k:&String) -> usize {
    s.len()
    // .try_into().unwrap()
}

一样正常输出The length of 'hello' is 5.而不用添加生命周期。

评论区

写评论
zkx 2023-03-19 15:39

可以翻一翻 reference 里的 lifetime 消除规则:Lifetime elision

本质上,每个引用都是有 lifetime 的,只不编译器在可以根据上下文推断出 lifetime 的时候,允许你不添加 lifetime。

回到第一个例子,由于你返回的是一个 usize,无论你添加多少个带引用的参数,这些参数的 lifetime 与 usize 都无关,此时编译器认为参数的 lifetime 为 '_,属于可以推断出来的场景。

第二个例子,你有两个带引用的参数,同时返回一个引用,编译器无法得知你返回结果的 lifetime 多长,因此需要你显示标注参数的 lifetime,并与返回结果关联起来。

rdigua 2023-03-16 17:36

引用不会获得值的所有权。

pader 2023-03-15 14:48

国为一个返回的 usize,一个是 &str 吧,这两个区别还是挺大,&str 是借用(引用),而 usize 却只是一个值而已,因为返回的 &str 和两个入参的生命周期息息相关,而 uszie 给出去后就已经不相关了。

我是猜的。

作者 berners 2023-03-13 19:21

报错内容是:

error[E0106]: missing lifetime specifier
  --> src/main.rs:17:29
   |
17 | fn longest(x:&str,y:&str )->&str{
   |              ----   ----    ^ expected named lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
help: consider introducing a named lifetime parameter
   |
17 | fn longest<'a>(x:&'a str,y:&'a str )->&'a str{
   |           ++++    ++        ++         ++

For more information about this error, try `rustc --explain E0106`.

--
👇
xh1109: 报错内容是:“mismatched types expected &str, found ()” ?

--
👇
berners: ``` fn first_word(s: &str) -> &str {}

提示报错,为什么?


xh1109 2023-03-13 16:51

报错内容是:“mismatched types expected &str, found ()” ?

--
👇
berners: ``` fn first_word(s: &str) -> &str {}

提示报错,为什么?
--  
👇  
dvorakchen: 

只是因为省略了而已,比如:

fn first_word(s: &str) -> &str {}


展开后是这样的:

fn first_word<'a>(s: &'a str) -> &'a str {}


在上面的方法中的生命周期标注编译器自己能够推断出来,所以可以省略掉

而且我们也不想对这些简单的生命周期注解,每个方法都写一遍

作者 berners 2023-03-13 16:45
fn first_word(s: &str) -> &str {}

提示报错,为什么?

👇
dvorakchen:

只是因为省略了而已,比如:

fn first_word(s: &str) -> &str {}

展开后是这样的:

fn first_word<'a>(s: &'a str) -> &'a str {}

在上面的方法中的生命周期标注编译器自己能够推断出来,所以可以省略掉

而且我们也不想对这些简单的生命周期注解,每个方法都写一遍

dvorakchen 2023-03-13 16:21

只是因为省略了而已,比如:

fn first_word(s: &str) -> &str {}

展开后是这样的:

fn first_word<'a>(s: &'a str) -> &'a str {}

在上面的方法中的生命周期标注编译器自己能够推断出来,所以可以省略掉

而且我们也不想对这些简单的生命周期注解,每个方法都写一遍

xh1109 2023-03-13 14:23
1 共 8 条评论, 1 页