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

Rust初始化结构体字段的规范实现:对比Ruby类及反模式判断

问题解答

1. 手动传self的写法是否属于反模式

你当前写的Workspace::list_files(workspace)不是反模式,这是Rust方法调用的底层展开形式,但日常开发不会这么写:Rust提供了更符合使用习惯的语法糖,只要方法的第一个参数是self/&self/&mut self,就可以直接用实例.方法名()的形式调用,编译器会自动帮你把实例传入第一个参数,和手动传参的效果完全一致。

另外你原有代码的list_files方法参数写的是self,会直接拿走实例的所有权,调用完之后workspace实例就会被销毁无法继续使用,对应原Ruby的需求,应该改成&self(不可变借用)即可。

2. Rust结构体初始化的最优实践

Rust没有内置的类构造函数语法,社区约定俗成用new关联函数作为构造器,这就是标准的最优实现,没有其他更特殊的语法。
你原有new方法的思路是正确的,只是字段类型选型不符合场景:原Ruby中pathname是路径类型,Rust里应该用PathBuf存储拥有所有权的路径,比你选用的i32更适配需求,也能兼容不同操作系统的路径格式。


修正后的完整实现代码

use std::path::{Path, PathBuf};
use std::io;

pub struct Workspace {
    pathname: PathBuf,
}

impl Workspace {
    // 构造函数,支持传入字符串、Path对象等多种路径格式
    pub fn new(pathname: impl AsRef<Path>) -> Self {
        Self {
            pathname: pathname.as_ref().to_path_buf()
        }
    }

    // 用&self借用实例,调用后不影响实例的后续使用
    pub fn list_files(&self) -> io::Result<Vec<PathBuf>> {
        // 对应原Ruby Dir.entries的功能,读取路径下所有文件
        let mut entries = Vec::new();
        for entry in std::fs::read_dir(&self.pathname)? {
            entries.push(entry?.path());
        }
        Ok(entries)
    }
}

调用示例

fn main() -> io::Result<()> {
    let workspace = Workspace::new("./target_directory");
    // 直接用实例调用方法,不需要手动传self
    let files = workspace.list_files()?;
    for file in files {
        println!("{}", file.display());
    }
    // 方法调用结束后workspace仍可正常使用
    Ok(())
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:27:03