簡體   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