我可以接受两个 &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 方法可以像我最初打算的那样做到这一点。
只要参数 singular
和 plural
还活着,你就可以告诉 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 条规则匹配,因此编译器要求您明确指定生命周期。
所以我尝试实现这个功能:
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 方法可以像我最初打算的那样做到这一点。
只要参数 singular
和 plural
还活着,你就可以告诉 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 条规则匹配,因此编译器要求您明确指定生命周期。