在处理if / else中的不兼容类型时,如何删除重复?

时间:2017-05-19 12:10:41

标签: rust

我的方法decode_message有2个实现,一个用于BufReader<Read>,另一个用于BufReader<Read + Seek>。专业化已启用。

if is_stdin {
    let mut reader = BufReader::with_capacity(1000, io::stdin());
    decode_message(reader)
} else {
    let filename = &args[1];
    let mut reader = BufReader::with_capacity(1000, File::open(filename).unwrap());
    decode_message(reader)
};

上面的代码有效,但令人讨厌的是我必须在每个分支中重复decode_message

1 个答案:

答案 0 :(得分:1)

就你的问题所显示,专业化不是罪魁祸首,只是使用单态:两个条件范围中定义的reader绑定,鉴于BufReader::new的定义,将是不同的并且不能分配给相同的绑定。每次运行时条件导致值类型的分歧时,例如在这种情况下,它们也将导致无法在它们之间共享的代码例程。

当然,有一个例外:trait对象的具体类型已被删除,因此绑定reader: BufReader<Box<Read>>,甚至reader: Box<BufRead>可以在条件语句中保存两个读者中的任何一个。但是,生成的代码可能无法更好地执行,因为它会从方法解析中产生运行时成本,并阻止某些提前优化。

因此,没有比现有方法更好的方法了。 实际上,这里已经应用了一个好的模式:你可以使用单态函数来包含从单态转移的剩余逻辑,直到它收敛到相同的类型。有了它,您只需重复decode_message()次呼叫而不是其中的所有内容。