【问题标题】:Why Rust compiler doesn't consider Box<FileRotate<_>> as valid a implementation for Box<(dyn std::io::Write + Send + 'static)?为什么 Rust 编译器不认为 Box<FileRotate<_>> 是 Box<(dyn std::io::Write + Send + 'static) 的有效实现?
【发布时间】:2022-01-19 14:18:10
【问题描述】:

我正在尝试将旋转日志与fern 结合起来,通过将盒装FileRotate 实例(来自file-rotate 板条箱)与fern Dispatch 实例链接起来,但似乎无法满足编译器.这是代码sn-p:

let log= Box::new(
    FileRotate::new(
        "log/output.log",
        CountSuffix::new(2),
        ContentLimit::Lines(10),
        Compression::None));

fern::Dispatch::new()
    .level(LevelFilter::Debug)
    .chain(log)
    .apply()?;

编译器不同意,出现如下错误:

error[E0277]: the trait bound `fern::Output: From<Box<FileRotate<CountSuffix>>>` is not satisfied
   --> src/main.rs:101:16
    |
101 |         .chain(log)
    |          ----- ^^^ the trait `From<Box<FileRotate<CountSuffix>>>` is not implemented for `fern::Output`
    |          |
    |          required by a bound introduced by this call
    |
    = help: the following implementations were found:
              <fern::Output as From<&'static (dyn log::Log + 'static)>>
              <fern::Output as From<Box<(dyn log::Log + 'static)>>>
              <fern::Output as From<Box<(dyn std::io::Write + Send + 'static)>>>
              <fern::Output as From<Dispatch>>
            and 6 others
    = note: required because of the requirements on the impl of `Into<fern::Output>` for `Box<FileRotate<CountSuffix>>`
note: required by a bound in `Dispatch::chain`
   --> /Users/l203663/.cargo/registry/src/github.com-1ecc6299db9ec823/fern-0.6.0/src/builders.rs:195:21
    |
195 |     pub fn chain<T: Into<Output>>(mut self, logger: T) -> Self {
    |                     ^^^^^^^^^^^^ required by this bound in `Dispatch::chain`

但是,FileRotate 结构体同时实现了WriteSend,正如herehere 所记录的那样。

编译器提出的最接近的实现是 IMO:

From<Box<(dyn std::io::Write + Send + 'static)>>
  • 问题是由'static 生命周期引起的吗?在这种情况下,我该如何解决?
  • 如果不是,可能是什么原因造成的?

正在使用的箱子:

log = "0.4.14"
fern = "0.6.0"
file-rotate = "0.5.3" 

【问题讨论】:

  • log 的类型显式注释为Box&lt;(dyn std::io::Write + Send + 'static)&gt; 是否提供任何有用的信息?
  • 感谢@SolomonUcko,这似乎有效。但是,我发现as 构造更清洁,如投票答案中所示。

标签: logging rust


【解决方案1】:

我不确定这就是问题的全部(没有使用过fern),但由于chain() 的输入参数是通用的,它不会自动将您的Box&lt;FileRotate&gt; 强制转换为Box&lt;dyn Write + Send&gt;,所以你必须明确地这样做:

.chain(log as Box<dyn Write + Send>)

您不需要指定'static,因为这是所有Box&lt;dyn ...&gt;(但不是&amp;dyn ...)的默认值。

【讨论】:

  • 正如您所提到的,chain 方法具有以下签名:pub fn chain&lt;T: Into&lt;Output&gt;&gt;(self, logger: T) -&gt; Self。您关于 Rust 无法从泛型类型强制转换的说法是有道理的,尽管我在在线文档中找不到。我可能忽略了它。
猜你喜欢
  • 2018-06-09
  • 2020-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-18
  • 2020-10-08
  • 2021-12-04
相关资源
最近更新 更多