You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现Deref trait返回&String报错,为何PathBuf可返回引用?

关于Deref trait实现返回引用的问题解析

你的代码为什么报错

你写的MyDir的Deref实现里,deref函数内的txt是个局部变量——它是在函数栈上创建的临时字符串,函数执行完毕后就会被销毁。返回它的引用相当于返回了一个指向已释放内存的指针,也就是悬垂引用,Rust的安全机制自然会直接报错拦截。

PathBuf的Deref实现为啥没问题

看PathBuf的代码:

[stable(feature = "rust1", since = "1.0.0")]
impl ops::Deref for PathBuf {
    type Target = Path;
    #[inline]
    fn deref(&self) -> &Path {
        Path::new(&self.inner)
    }
}

这里的Path::new根本没创建新的所有权数据。Path本身是个引用类型(胖指针),&self.inner是指向PathBuf自身持有的inner字段的引用,Path::new只是把这个引用转换成&Path类型而已。返回的&Path实际引用的是PathBuf结构体自身拥有的数据,生命周期和self完全一致,完全符合Rust的安全规则。

修正你的代码的几种方式

如果你非要通过Deref返回格式化后的字符串引用,必须把这个格式化后的字符串存在MyDir里,不能临时创建:

use std::ops;

struct MyDir {
    path: String,
    display_str: String, // 预先存好格式化后的字符串
}

impl MyDir {
    fn new(path: String) -> Self {
        let display_str = format!("Dir[path = {}]", path);
        MyDir { path, display_str }
    }
}

impl ops::Deref for MyDir {
    type Target = String;

    fn deref(&self) -> &String {
        &self.display_str
    }
}

fn main() {
    let dir = MyDir::new("/home/user".to_string());
    println!("{}", *dir); // 输出 Dir[path = /home/user]
}

要是只是需要格式化后的字符串,其实没必要实现Deref,给MyDir加个方法更直接:

use std::ops;

struct MyDir {
    path: String,
}

impl MyDir {
    fn display(&self) -> String {
        format!("Dir[path = {}]", self.path)
    }
}

fn main() {
    let dir = MyDir { path: "/home/user".to_string() };
    println!("{}", dir.display());
}

内容的提问来源于stack exchange,提问作者Saber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:42:39