rust - 实施可选特征要求
问题描述
我正在尝试找到一种方法来对不同的特征进行分组,以便通用变量可以保存这些特征。
例如,我试图让 T 具有 io::Read + io::Write + io::Seek 的特征。现在,可以使用以下代码在 rust 中轻松完成:
pub trait RWS: io::Read + io::Write + io::Seek{}
impl<T> RWS for T where T: io::Read + io::Write + io::Seek{}
然而,当试图拥有一个接收 BufReader 的函数时,问题就出现了,因为 BufReader 没有实现 io::Write。
因此,是否有可能为可以是任何一种的通用类型实现如下所示的东西?
pub trait RWS: io::Read || io::Write || io::Seek{}
impl<T> RWS for T where T: io::Read || io::Write || io::Seek{}
解决方案
如果您只需要一个可以一次存储实现这三个特征之一的任何内容的字段,我建议使用一个简单的枚举:
enum RWS<'a> { // The lifetime parameter can be omitted if you will only be storing fields of `'static` type.
Read(Box<dyn Read + 'a>),
Write(Box<dyn Write + 'a>),
Seek(Box<dyn Seek + 'a>),
}
为方便起见,您可以向此枚举添加from_read
, from_write
,from_seek
构造函数,并在结构的方法中对其进行匹配。
但是,这种方法有一些限制。由于它拥有值的所有权并删除其具体类型,因此您不能执行以下操作:
let bufreader: std::io::BufReader = /* ... */;
self.rws = RWS::Read(Box::new(bufreader));
// later...
if let self.rws = RWS::Read(val) {
self.rws = RWS::Seek(val); // compile error, even though `BufReader` impls `Seek`
}
推荐阅读
- c# - 标题上方的 WPF 数据网格标题
- model-view-controller - MVC 返回 URL 建议
- javascript - 使用链接替换标签值,类似于选择标签
- c# - 将 MapElementsLayer 添加到 MapControl - UWP C#
- java - JPA:getReference()与仅具有ID的新“模拟”对象?
- bash - Bash 运算符:“!” 与“-z”
- javascript - 如何停止
- 重叠的元素?
- sql - 使用 Oracle SQL 创建动态列
- php - 如何反转 preg_match_all php
- unit-testing - 如果我使用可观察的延迟,如何编写 ngrx/效果单元测试用例?