繁体   English   中英

为什么在泛型函数中“预期命名生命周期参数”

[英]Why "expected named lifetime parameter" in a generic function

如果我写一个这样的函数:

fn parse_json<'a, T: Deserialize<'a>>(s: &'a str) -> Vec<T> {
    serde_json::from_str(s).unwrap()
}

它按预期工作。 但是,如果我尝试在不显式声明生命周期的情况下执行相同的操作,如下所示:

fn parse_json<T: Deserialize>(s: &str) -> Vec<T> {
    serde_json::from_str(s).unwrap()
}

我收到编译器错误:

| fn parse_json<T: Deserialize>(s: &str) -> Vec<T> {
|                  ^^^^^^^^^^^ expected named lifetime parameter

为什么? 在这种情况下,编译器是否有理由要求明确的生命周期声明?

如果我没有使用泛型而是具体类型,我就不需要显式声明任何生命周期:

fn parse_json(s: &str) -> Vec<MyStruct>   // that compiles file

我相信,这是由于所谓的终生省略规则 问题是,为什么带有泛型返回类型的版本也没有被省略规则覆盖?

从 serde文档中Deserialize是在一些明确的生命周期内实现的:

此特征的 'de 生命周期是反序列化时 Self 可能借用的数据的生命周期

所以你需要提供它。 此外,由于s是反序列化的借用值,因此它应该与其生命周期相匹配,如上所述:

fn parse_json<'de, T: Deserialize<'de>>(s: &'de str) -> Vec<T> {
    serde_json::from_str(s).unwrap()
}

操场

生命周期省略适用于函数参数和返回类型,但目前不适用于特征边界,例如T: Deserialize

为什么? 在这种情况下,编译器是否有理由要求明确的生命周期声明?

我不确定,但总的来说,生命周期省略规则相当有限,大概是为了使它们更容易理解并减少引入令人困惑的编译器“魔术”的机会。


需要注意的是一辈子省音在泛型参数支持的,但它是半弃用(见elided_lifetimes_in_paths皮棉):

struct Foo<'a>(&'a str);

// Compiles, but causes a warning with `#![warn(rust_2018_idioms)]`
fn bar1(s: &str) -> Foo { Foo(s) }

// Compiles, does not cause warning
fn bar2(s: &str) -> Foo<'_> { Foo(s) }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM