繁体   English   中英

创建一个返回空结构实现的工厂类

[英]Create a factory class that returns an empty-struct implementation

我想为格式化程序创建一个通用接口,它将根据其目的进行输入和格式化。

目前我正在返回一个包含格式化程序实现的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;

在Rust中这样做的正确方法是什么?

由于Formatter实现是空结构,因此为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);

这会产生输出:

0x1
0x1

ZST(零大小类型)通常以特殊方式处理。 所以至少你知道你不支付堆分配。 但请注意, Box<Formatter>的内存布局是一个胖指针,如下所示: (*mut Formatter, *mut VTable) 第一个指针始终为0x1 ,第二个指针指向静态分配的包含函数指针( vtable - Wikipedia )的调度表。 这在你的情况下可能很好。


另一种可能性是创建一个这样的枚举:

enum FormatterSd {
    Json(JsonFormatter),
    Xml(XmlFormatter),
}

现在你可以Formatter for FormatterSd实现Formatter for FormatterSd ; 在此实现中,您将使用简单的match块来执行调度。 这样你就不需要使用Box


最后:您不需要工厂类型! 看起来有点像你试图将强大的OO编程语言中的想法带入Rust。 通常,这不是最佳或最惯用的解决方案。 例如,Rust中有自由函数。 所以你可以简单地写:

fn get_formatter(format: &str) -> Result<Box<Formatter>, Error> {
    // ...
}

是的,没有Factory类型! Rust中的空类型比空类少得多(意思是:没有任何字段)。 你可以只为这种东西使用自由函数,不需要将它与一个类型相关联。

最后:您不需要从Box手动获取引用:

let formatter = &*formatter_box as &Formatter;

你可以简单地说formatter_box.format_information(...); ,多亏了deref强制。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM