从函数的堆栈返回对 Path 的引用是如何工作的?
How does returning a reference to Path from the function's stack work?
以下代码片段来自 path.rs
的 rust 源代码
impl AsRef<Path> for String {
fn as_ref(&self) -> &Path {
Path::new(self)
}
}
它似乎从堆栈帧返回一个新创建的 Path
对象的引用。它如何绕过 Rust 的借用检查规则?堆栈对象的生命周期应该只针对当前帧,返回临时对象的引用应该会产生错误。
returned 引用不指向在 as_ref()
中新创建的某个对象,而是指向作为参数传入的字符串的数据。
让我们明确相关函数的生命周期。原型
fn as_ref(&self) -> &Path
可以脱糖为
fn as_ref(&'a self) -> &'a Path
self
的类型是 &'a String
,对生命周期为 'a
的字符串的引用。
在函数体内,调用了Path::new()
。根据文档,它是这样定义的:
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path
加上省略的生命周期得到
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &'a S) -> &'a Path
因此新创建的 Path
引用将与我们传入的引用具有相同的生命周期,这正是 return 值所需的生命周期。
以下代码片段来自 path.rs
的 rust 源代码impl AsRef<Path> for String {
fn as_ref(&self) -> &Path {
Path::new(self)
}
}
它似乎从堆栈帧返回一个新创建的 Path
对象的引用。它如何绕过 Rust 的借用检查规则?堆栈对象的生命周期应该只针对当前帧,返回临时对象的引用应该会产生错误。
returned 引用不指向在 as_ref()
中新创建的某个对象,而是指向作为参数传入的字符串的数据。
让我们明确相关函数的生命周期。原型
fn as_ref(&self) -> &Path
可以脱糖为
fn as_ref(&'a self) -> &'a Path
self
的类型是 &'a String
,对生命周期为 'a
的字符串的引用。
在函数体内,调用了Path::new()
。根据文档,它是这样定义的:
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &Path
加上省略的生命周期得到
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &'a S) -> &'a Path
因此新创建的 Path
引用将与我们传入的引用具有相同的生命周期,这正是 return 值所需的生命周期。