【问题标题】:Implementing optional trait requirement实施可选特征要求
【发布时间】:2021-03-25 05:04:58
【问题描述】:

我正在尝试找到一种方法来对不同的特征进行分组,以便通用变量可以容纳这些特征。

例如,我试图让 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{}

【问题讨论】:

  • 你打算用RWS trait 做什么?这三个特征暴露了不同的功能,所以我不太明白如何将它们统一在一个特征RWS
  • @AlphaModder 我并没有尝试使用所有这些,我试图对其中任何一个强加要求。对于 RWS,我试图在结构 io 中存储一个字段,以便它可以是(读、写、查找)之一。这个io 字段将根据调用的函数而改变。这就是我希望它灵活的原因。
  • 我明白了。那么存储在该字段中的类型会在结构的生命周期内发生变化吗?它是否需要同时使用多个,还是能够一次将其用作ReadWriteSeek 之一?
  • @AlphaModder 是的,该结构中的类型将在整个生命周期内发生变化。我想我把它编程为使用一个。

标签: rust


【解决方案1】:

如果您只需要一个可以一次存储实现这三个特征之一的任何内容的字段,我建议使用一个简单的枚举:

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_readfrom_writefrom_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`
} 

【讨论】:

  • 谢谢!枚举和重构我的代码似乎是我唯一的选择,因为没有其他办法。
猜你喜欢
  • 2017-07-25
  • 2021-02-06
  • 2013-02-08
  • 2017-09-14
  • 2020-07-16
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-09
相关资源
最近更新 更多