常量字符串/字符串字面量的生命周期是如何工作的?

10
我阅读了官方网站上的教程,对于常量字符串/字符串字面值的生命周期有一些疑问。
当我编写以下代码时,会出现错误:
fn get_str() -> &str {
    "Hello World"
}

错误:
error[E0106]: missing lifetime specifier
 --> src/main.rs:1:17
  |
1 | fn get_str() -> &str {
  |                 ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
  = help: consider giving it a 'static lifetime

然而,当我添加一个参数时,它就可以了:

fn get_str(s: &str) -> &str {
    "Hello World"
}

这为什么有效?即使与参数无关,"Hello World"如何借用的特性?
1个回答

20

生命周期省略推断出完整的类型为

fn get_str(s: &str) -> &str

fn get_str<'a>(s: &'a str) -> &'a str

这基本意味着get_str的返回值必须在s有效期内保持有效。"字符串常量\"Hello world\""的实际类型为&'static str,这意味着它在程序的整个运行期间都是有效的。由于此满足函数签名中的生命周期限制(因为'static始终包括任何'a),所以可以正常工作。
然而,使原始代码正常工作的更明智的方法是在函数类型中添加一个显式生命周期。
fn get_str() -> &'static str {
    "Hello World"
}

“Hello World”如何从参数‘s’中借用,即使它与‘s’无关?
在具有单个引用参数的函数中,只有两种选项对于返回值的生命周期才有意义:
1. 它可以是“static”,就像你的例子一样;或者 2. 返回值的生存期必须与参数的生存期相关联,这就是生存期省略的默认设置。
在本帖子顶部的链接中选择后者的一些原因,但基本上归结为后者是更常见的情况。请注意,生存期省略根本不会查看函数体,它只根据函数签名进行操作。这就是为什么它不会考虑您只返回字符串常量的事实。

1
@MatthieuM。感谢您的编辑。在发布之前,我应该真正编译我的代码。 - fjh
在我看来,应用一些简单的生命周期省略规则与“推断”没有任何关系,这就是为什么我不会在这个上下文中使用那个词的原因。 - sellibitze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接