为什么Rust函数签名中使用带生命周期的结构体需显式标注?
Rust 生命周期标注的契约规则
首先明确两个核心规则,就能搞懂这个疑惑:
- 生命周期是类型的一部分,所有携带生命周期泛型的类型,使用时必须指定生命周期参数,没有例外。
- 函数签名是对外的公开契约,Rust 不允许编译器自动推导签名的约束,所有类型、生命周期信息必须显式声明(或使用标准的省略语法表示遵循约定)。
两个场景的差异本质
1. 调用longest时不需要手动标注的原因
这是调用侧的生命周期自动推导生效:编译器可以根据你传入函数的两个字符串实参的实际生命周期,自动匹配泛型参数'a的具体取值,不需要开发者手动指定,和调用泛型函数时编译器自动推导泛型类型的逻辑完全一致。
2. 函数签名中必须写News<'_>的原因
这里的'_是 Rust 的匿名生命周期省略语法,不是额外要求添加的内容,是类型本身必须存在的部分:
News是定义了生命周期泛型的结构体,<'a>是它类型的一部分,就像Vec<T>不能直接写成Vec使用一样,News不能单独作为类型使用,必须指定它的生命周期参数。- 你也可以选择手动给生命周期命名,比如写成
News<'a>,但需要在函数名后声明对应的泛型参数:async fn submit<'a>(n: Json<News<'a>>) -> Status,和你定义longest函数时需要先声明<'a>的逻辑完全一致。使用'_只是让编译器自动按照生命周期省略规则处理这个参数,简化写法而已,不是额外加的约束。
为什么编译器不能直接省略这个标注
Rust 从设计上就禁止推导函数签名的内容:如果允许编译器自动推导函数签名的生命周期约束,那么函数内部实现的修改可能会偷偷改变对外的契约,导致调用侧出现意料之外的编译错误,显式的签名约束就是为了把对外承诺的行为固定下来,避免隐式变更。
内容的提问来源于stack exchange,提问作者keddad
相关产品推荐
相关产品推荐

