struct的两种实现有什么区别吗?

问题描述 投票:0回答:1
struct ImportantExcerpt<'a> {
    part: &'a str,
}

impl<'a> ImportantExcerpt<'a> {
    fn level(&'a self) -> i32 {
        3
    }
}

struct ImportantExcerpt<'a> {
    part: &'a str,
}

impl<'a, 'b> ImportantExcerpt<'a> {
    fn level(self: &'b ImportantExcerpt<'a>) -> i32 {
        3
    }
}

它们都可以编译。

rust lifetime
1个回答
0
投票

在下面的示例中,

level()
的两个版本是
level_1()
level_2()

实际上并没有什么区别,因为这些函数返回一个,而不是一个引用,因此生命周期的微妙之处不会改变任何东西:返回的值将独立存在。
示例中使用了这两个版本,我们看不到生命周期约束有任何差异。
然而,如果我们想返回一个引用,如
text_1()
text_4()
,那么必须仔细考虑
self
周围的生命周期。

text_1()
level_1()
的直接改编。
lifetime elision rules
告诉我们,结果
&str
的生命周期是
self
参数的生命周期(
'a
此处明确给出)。
(请注意,我不确定为结构本身和对它的引用编写相同的生命周期是否有意义;比我更了解 Rust 的人可以围绕这一点进行开发)
这意味着由此产生的
&str
的寿命不得长于结构;这在示例中显示为错误。

text_2()
level_2()
的直接改编。
lifetime elision rules
告诉我们,结果
&str
的生命周期是
self
参数的生命周期(
'b
此处明确给出)。
那么,这相当于
text_3()
,结果与
text_1()
相同。
这意味着由此产生的
&str
的寿命不得长于结构;这在示例中显示为错误。

当涉及到

text_4()
时,我们明确为生成的
&str
提供生命周期,这与
self
引用的生命周期不同。
这实际上与结构中内部使用的
part
的生命周期相同。
这意味着生成的
&str
的寿命不得比用于初始化
part
的原始字符串长,但它根本不链接到结构本身;该示例表明,在删除结构后仍然可以使用生成的
&str

struct ImportantExcerpt<'a> {
    part: &'a str,
}

impl<'a, 'b> ImportantExcerpt<'a> {
    fn level_1(&'a self) -> i32 {
        3
    }
    fn text_1(&'a self) -> &str {
        self.part
    }
    fn level_2(self: &'b ImportantExcerpt<'a>) -> i32 {
        3
    }
    fn text_2(self: &'b ImportantExcerpt<'a>) -> &str {
        self.part
    }
    fn text_3(self: &'b ImportantExcerpt<'a>) -> &'b str {
        self.part
    }
    fn text_4(self: &'b ImportantExcerpt<'a>) -> &'a str {
        self.part
    }
}

fn main() {
    let f_txt = "first".to_owned();
    let f_out = {
        let ie = ImportantExcerpt {
            part: f_txt.as_str(),
        };
        // (ie.text_1(), ie.level_1()) // `ie` dropped here while still borrowed
        // (ie.text_2(), ie.level_1()) // `ie` dropped here while still borrowed
        // (ie.text_3(), ie.level_1()) // `ie` dropped here while still borrowed
        (ie.text_4(), ie.level_1()) // correct
    };
    println!("{:?}", f_out);

    let s_txt = "second".to_owned();
    let s_out = {
        let ie = ImportantExcerpt {
            part: s_txt.as_str(),
        };
        // (ie.text_1(), ie.level_2()) // `ie` dropped here while still borrowed
        // (ie.text_2(), ie.level_2()) // `ie` dropped here while still borrowed
        // (ie.text_3(), ie.level_2()) // `ie` dropped here while still borrowed
        (ie.text_4(), ie.level_2()) // correct
    };
    println!("{:?}", s_out);
}
/*
("first", 3)
("second", 3)
*/
© www.soinside.com 2019 - 2024. All rights reserved.