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
相关产品推荐
相关产品推荐

