链式调用TempDir方法为何导致File::create创建文件失败?
问题原因与解决方法
核心问题和expect无关,是**TempDir的生命周期管理**导致的:
第一种写法中,
temp_dir_path绑定了TempDir实例,这个实例会一直存活到变量离开作用域(也就是你完成文件读写、断言等所有操作之后)。临时目录在整个过程中都存在,所以文件创建能正常执行。第二种链式调用写法里,
TempDir::new(...).expect(...)返回的实例,在调用.path()之后就没有任何变量持有它的所有权了——Rust会在这个表达式执行完毕后立刻销毁这个TempDir实例。而TempDir的Drop特性实现会在实例销毁时自动删除整个临时目录,这就导致后续File::create(&path)执行时,目标文件的父目录已经不存在,自然创建失败。
修复方案
只要确保TempDir实例存活到文件操作完成即可,最简单的方式是保留实例的变量绑定:
let temp_dir = TempDir::new("directory").expect("couldn't create directory"); let path = temp_dir.path().join("test-file.json"); let mut temp_file = File::create(&path).expect("failed to create file"); writeln!(temp_file, "{{\"key\": 2}}").expect("write failed"); // 读取文件并进行断言等操作
或者如果偏好链式风格,可以通过元组同时持有实例和路径,延长实例生命周期:
let (temp_dir, path) = { let dir = TempDir::new("directory").expect("couldn't create directory"); let file_path = dir.path().join("test-file.json"); (dir, file_path) }; let mut temp_file = File::create(&path).expect("failed to create file"); writeln!(temp_file, "{{\"key\": 2}}").expect("write failed");
本质上是要遵守Rust的所有权规则:持有临时资源的实例必须存活到所有依赖该资源的操作完成,不能让实例提前被自动清理。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

