【发布时间】:2017-08-12 09:21:34
【问题描述】:
我正在尝试从回调内部返回对数据数组的引用。由于生命周期,下面的 sn-p 是不可能的,但我还是添加了它以提供更好的上下文。
我想实现某种虚拟文件系统。我想使用返回类型&[u8],因为我正在考虑使用mmap 以及看起来很有希望的实现暴露&[u8] 来访问数据。
现在这有点过头了,所以我想专注于回调来读取并返回传递给它的文件的内容。
这样做的惯用方式是什么?
use std::fs::File;
use std::io::prelude::*;
fn main() {
test(&|path| {
if false {
let mut data: Vec<u8> = Vec::new();
let mut file = File::open(path).unwrap();
file.read_to_end(&mut data).unwrap();
return Some(&data);
}
None
});
}
// loads various files. I do not care about them anymore once this function returns
pub fn test<'a>(loader: &Fn(&str) -> Option<&'a [u8]>) {}
【问题讨论】:
-
在这种情况下,闭包和函数没有区别。
-
此外,接受泛型
F其中F: Fn(&str),而不是特征对象&Fn(&str)更为惯用。 -
虽然问题表面上相似,但其他问题的答案在这里并不适用。在这种情况下,OP 正在询问如何做一些真正有意义的事情,他们只是错误地接近它。具体来说,OP 需要重构代码,以便 clsoure 不会直接返回引用。相反,闭包应该返回一个管理资源生命周期的对象,并且提供了一个获取引用的方法。为了使
test可用于不同的资源,闭包应该可能返回一个装箱的 trait 对象。 (详情见我的回答。) -
@user4815162342 OP 明确表示忽略他们将使用
mmap的事实,所以我做到了。如果您认为这个问题实际上是关于返回一个装箱的 trait 对象,我们可以更改问题以澄清,但这会使 other 现有答案无效。你觉得三个错误中哪一个是较小的罪? -
@Shepmaster 据我了解,OP 希望首先测试设计的其他方面,而不是立即实现完整的
mmap逻辑。另一方面,interface(闭包的签名)应该足够灵活,以便稍后添加对mmap的支持——这就是OP 想要返回&[u8]的原因。但这是我的理解,我自己当然不会改变这个问题 - 如果他们在阅读这些 cmets 后选择这样做,则取决于 OP。保留两个答案都很好,每个答案都在其对问题的理解范围内有效。
标签: rust