我可以接受两个 &str 参数和 return 一个或另一个吗?

Can I accept two &str params and return one or the other?

所以我尝试实现这个功能:

pub fn pluralize(singular: &str, plural: &str, count: u64) -> &str {
    if count == 1 {
        singular
    } else {
        plural
    }
}

但是我得到一个终生错误:

error[E0106]: missing lifetime specifier
   --> test.rs:165:63
    |
165 | pub fn pluralize(singular: &str, plural: &str, count: u64) -> &str {
    |                                                               ^ expected lifetime parameter
    |
    = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `singular` or `plural`

我可以通过返回字符串而不是 &str 并在每个输入上调用 to_string() 来使其编译和工作。但这效率较低,所以我想知道是否有 good/idomatic 方法可以像我最初打算的那样做到这一点。

只要参数 singularplural 还活着,你就可以告诉 Rust 结果是活着的:

fn pluralize<'a>(singular: &'a str, plural: &'a str, count: u64) -> &'a str {
    // ...
}

请注意,这会阻止您执行以下操作:

let singular = "one".to_string();
let pluralized = {
    let plural = "two".to_string();
    pluralize(&singular, &plural, 1)
};
println!("{:?}", pluralized);

也就是说,即使 pluralized 是对 singular 的引用,它的寿命足以在最后打印出来,Rust 假设它也可以是对 [=16= 的引用],它在最终打印语句之前超出了范围。编译器因此告诉你:

error[E0597]: `plural` does not live long enough
  --> test.rs:9:30
   |
7  |     let pluralized = {
   |         ---------- borrow later stored here
8  |         let plural = "two".to_string();
9  |         pluralize(&singular, &plural, 1)
   |                              ^^^^^^^ borrowed value does not live long enough
10 |     };
   |     - `plural` dropped here while still borrowed

一般来说,Rust 通常需要参数和 return 类型函数的显式生命周期:

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

这意味着 do_nothing 是一个函数,它接受一个生命周期为 'a 的参数,并且 return 是一个具有相同生命周期 'a 的引用。但在大多数常见情况下,编译器会实施一些合理的规则来猜测结果类型的生命周期。这允许您省略参数和结果类型的生命周期,如下所示:

fn do_nothing(s: &str) -> &str { ... }

规则是:

  • Each elided lifetime in the parameters becomes a distinct lifetime parameter.
  • If there is exactly one lifetime used in the parameters (elided or not), that lifetime is assigned to all elided output lifetimes.
  • If the receiver has type &Self or &mut Self, then the lifetime of that reference to Self is assigned to all elided output lifetime parameters.

(来自 https://doc.rust-lang.org/stable/reference/lifetime-elision.html

在您的示例中,参数中有两个生命周期(每个 &str 引用一个)。 None 条规则匹配,因此编译器要求您明确指定生命周期。