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

Memory 创建一个返回空结构实现的工厂类,memory,struct,rust,heap-memory,Memory,Struct,Rust,Heap Memory,我想为格式化程序创建一个通用接口,该接口将接受输入,并根据其用途对其进行格式化 目前,我返回一个包含格式化程序实现(包装到结果中)的框。但我不认为这是最好的方法。由于格式化程序实现是空结构,为一个框分配堆内存是没有意义的 pub trait Formatter { fn format_information(&self, information: Result<Information, Error>) -> Result<String, Error>

我想为格式化程序创建一个通用接口,该接口将接受输入,并根据其用途对其进行格式化

目前,我返回一个包含格式化程序实现(包装到结果中)的框。但我不认为这是最好的方法。由于格式化程序实现是空结构,为一个框分配堆内存是没有意义的

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;
pub特征格式化程序{
fn格式_信息(&self,信息:结果)->结果;
fn格式\u信息\u收集(&self,信息:InformationCollection)->结果;
}
发布结构JsonFormatter;
JsonFormatter{…}的impl格式化程序
pub结构XmlFormatter;
XmlFormatter{…}的impl格式化程序
//工厂创建格式化程序
酒吧结构工厂;
impl工厂{
pub fn get_格式化程序(格式:&str)->结果{
匹配格式{
“json”=>Ok(Box::new(JsonFormatter{})),
“xml”=>Ok(Box::new(XmlFormatter{})),
_=>Err(Error::new(format!(“找不到{}格式的格式化程序”,format)))
}
}
}
//使用工厂
let formatter_box=Factory::get_formatter(format).unwrap();
将formatter=&*formatter_框设为&formatter;
在生锈的情况下,正确的方法是什么

由于格式化程序实现是空结构,因此为
分配堆内存没有意义

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;
由于这没有任何意义,堆内存根本不会被分配。让我们试试它():

这将产生以下输出:

0x1
0x1
ZST(零尺寸类型)通常以特殊方式处理。所以,至少你知道你没有在这里为堆分配付费。但是请注意,
框的内存布局是一个胖指针,看起来像这样:
(*mut Formatter,*mut VTable)
。第一个指针总是
0x1
,第二个指针指向静态分配的分派表,其中包含函数指针()。这在你的情况下可能是好的


另一种可能是创建如下枚举:

enum FormatterSd {
    Json(JsonFormatter),
    Xml(XmlFormatter),
}
现在您可以为FormatterSd实现
格式化程序
;在这个实现中,您将使用简单的
match
块进行分派。这样您就不需要使用
Box


最后:你不需要有一个工厂类型!这似乎有点像是你试图将一种强大的OO编程语言的思想引入Rust。通常,这不是最好或最惯用的解决方案。例如,Rust中有自由函数。所以你可以简单地写:

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

您可以简单地说
formatter\u box.format\u信息(…),感谢deref强制

谢谢你的回答。我学到了很多。我从Rust开始,我的工作日语言是PHP:)
let formatter = &*formatter_box as &Formatter;