cun*_*ndd 3 memory struct heap-memory rust
我想为格式化程序创建一个通用接口,它将根据其目的进行输入和格式化.
目前我正在返回一个包含格式化程序实现的Box(包含在Result中).但我不认为这是最好的方法.由于Formatter实现是空结构,因此为Box分配堆内存没有意义.
pub trait Formatter {
fn format_information(&self, information: Result<Information, Error>) -> Result<String, Error>;
fn format_information_collection(&self, information: InformationCollection) -> Result<String, Error>;
}
pub struct JsonFormatter;
impl Formatter for JsonFormatter {...}
pub struct XmlFormatter;
impl Formatter for XmlFormatter {...}
// Factory to create a formatter
pub struct Factory;
impl Factory {
pub fn get_formatter(format: &str) -> Result<Box<Formatter>, Error> {
match format {
"json" => Ok(Box::new(JsonFormatter {})),
"xml" => Ok(Box::new(XmlFormatter {})),
_ => Err(Error::new(format!("No formatter found for format {}", format)))
}
}
}
// Use the factory
let formatter_box = Factory::get_formatter(format).unwrap();
let formatter = &*formatter_box as &Formatter;
Run Code Online (Sandbox Code Playgroud)
在Rust中这样做的正确方法是什么?
Luk*_*odt 10
由于Formatter实现是空结构,因此为a分配堆内存
Box没有意义.
而且由于它没有任何意义,因此根本不会分配堆内存.我们来试试吧(游乐场):
// `()` doesn't occupy any space, like e.g. your `JsonFormatter`
let b1 = Box::new(());
let b2 = Box::new(());
println!("{:p}\n{:p}", &*b1, &*b2);
Run Code Online (Sandbox Code Playgroud)
这会产生输出:
0x1
0x1
Run Code Online (Sandbox Code Playgroud)
ZST(零大小类型)通常以特殊方式处理.所以至少你知道你不支付堆分配.但请注意,你的内存布局Box<Formatter>是一个胖指针,如下所示:(*mut Formatter, *mut VTable).第一个指针始终是0x1,第二个指针指向一个静态分配的调度表,其中包含函数指针(vtable - Wikipedia).这在你的情况下可能很好.
另一种可能性是创建一个这样的枚举:
enum FormatterSd {
Json(JsonFormatter),
Xml(XmlFormatter),
}
Run Code Online (Sandbox Code Playgroud)
现在你可以实现Formatter for FormatterSd; 在此实现中,您将使用简单match块来执行调度.这样你就不需要使用了Box.
最后:您不需要工厂类型!看起来有点像你试图将强大的OO编程语言中的想法带入Rust.通常,这不是最佳或最惯用的解决方案.例如,Rust中有自由函数.所以你可以简单地写:
fn get_formatter(format: &str) -> Result<Box<Formatter>, Error> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
是的,没有Factory类型!Rust中的空类型比空类少得多(意思是:没有任何字段).你可以只为这种东西使用自由函数,不需要将它与一个类型相关联.
最后:您不需要手动从以下位置获取引用Box:
let formatter = &*formatter_box as &Formatter;
Run Code Online (Sandbox Code Playgroud)
你可以简单地说formatter_box.format_information(...);,感谢deref强制.
| 归档时间: |
|
| 查看次数: |
83 次 |
| 最近记录: |