`impl<'a> Config<'a> {` 的语法含义

Syntax meaning for `impl<'a> Config<'a> {`

对于以下代码:

struct Config<'a> {
    query: &'a str,
    filename: &'a str,
    case_sensitive: bool,
}

impl<'a> Config<'a> {
    pub fn new(args: &'a [String]) -> Result<Config, &'static str> {
        if args.len() < 3 {
            return Err("not enough arguments");
        }

        let query = &args[1];
        let filename = &args[2];

        let case_sensitive = env::var("CASE_INSENSITIVE").is_err();

        Ok(Config {
            query,
            filename,
            case_sensitive,
        })
    }
}

为什么需要 impl<'a> Config<'a> {,而不是 impl Config<'a> {

第一个和第二个'a的语法意义是什么?我知道'a是一个生命周期注解,但不知道为什么要把它放在implConfig之后。第一个 'a 做什么,第二个 'a 做什么?

第一个 <'a> 声明了一个上下文,该上下文引入了普遍量化的变量。换句话说,impl<'a> ... 表示 "implement for any possible lifetime 'a ... ".

引入变量后,第二个'a是将变量应用于类型。

您可以将语法 impl<'a> Config<'a> 解读为:"for any possible lifetime 'a these methods are defined for Config<'a>".

在更复杂的情况下,上下文是您可以对参数施加约束的地方。对于生命周期,这始终是 "outlives" 关系,例如 <'a, 'b: 'a> ("for all lifetimes 'a and 'b where 'b outlives 'a")。对于类型,这可能包括特征或生命周期界限,例如<'a, T: + Debug + 'a> ("for all lifetimes, 'a and all types T, where T implements Debug and does not outlive 'a").

所有泛型生命周期和类型都需要在某处声明。

尝试编译您的代码以使用 impl Config<'a>,您将收到此错误消息:

error[E0261]: use of undeclared lifetime name `'a`
 --> src/lib.rs:9:13
  |
9 | impl Config<'a> {
  |             ^^ undeclared lifetime

像类型参数一样,通用生命周期参数(例如 Config<'a> 中的 'a 需要在使用它们的每个函数、类型定义或特征实现上声明。它们甚至不必与参数最初声明的名称完全相同:

impl<'c> Config<'c> {
    ... // use 'c instead of 'a
}

另请参阅:

  • Rust 编程语言,Section 1.1 关于在方法定义中使用泛型数据类型;
  • Rust 编程语言,Section 10.2 关于使用特征边界有条件地实现方法。