Rust中显式声明self: &Self时self为何不是引用类型?
问题背景
根据《Rust程序设计语言》中的说明,我们已知:
&self实际上是self: &Self的简写形式
但在下方示例(fn get_name)中,我们显式编写了参数声明 self: &Self,编译器报错信息却显示self不是引用,而是对象本身,无法匹配返回值类型。为什么这种场景下self不是引用?&Self 中的&符号又起到什么作用?
示例:一个实现了返回姓名方法的简单结构体
struct Person { name: String } impl Person { fn new(name: &str) -> Person { Person { name: name.to_string() } } fn get_name(self: &Self) -> &String { self.name // Error: expected `&std::string::String`, found struct `std::string::String` } }
问题解答
首先要明确:&self 是 self: &Self 的简写是教材为了降低入门门槛给出的简化表述,二者并不是完全等价的,差异来自Rust对方法接收者的特殊语法糖规则。
&self是Rust专门为方法设计的接收者简写语法,它会隐式完成两个关键操作:- 给self的引用自动补上生命周期标注,等价于
&'a self - 自动将返回值中所有未标注生命周期的引用,和self的生命周期绑定,同时在字段访问、方法调用场景自动触发匹配的自动解引用、自动借用逻辑
- 给self的引用自动补上生命周期标注,等价于
- 当你手动写
self: &Self时,这里的&确实是用来标注self是&Self(即当前impl块里的&Person)引用类型的符号,但你漏掉了语法糖自动补全的生命周期信息:- 编译器无法判断返回值
&String的借用来源,没法自动把它的生命周期和self的引用绑定 - 生命周期关系不明确时,编译器不会触发字段访问的自动借用:此时
self.name会被识别为需要移动出来的String类型值,而非可以被借用的字段内存位置,自然和返回值要求的&String类型不匹配,就触发了你看到的报错。
- 编译器无法判断返回值
如果要手动写出和&self完全等价的显式接收者写法,需要把生命周期也显式标注出来:
fn get_name<'a>(self: &'a Self) -> &'a String { self.name }
写全生命周期后,编译器能明确返回值的引用是从self借用的,就会正常执行自动借用逻辑,代码可以顺利编译通过。
内容的提问来源于stack exchange,提问作者Jack Lien
相关产品推荐
相关产品推荐

