【问题标题】:Why does changing from a TcpStream to a trait cause "cannot borrow immutable borrowed content as mutable"?为什么从 TcpStream 更改为 trait 会导致“不能将不可变的借用内容借用为可变的”?
【发布时间】:2018-07-05 22:07:42
【问题描述】:

我想使用异步 IO 创建一个 SOCKS5 代理的变体。我以前在 Haskell 中做过这个,所以我认为这将是一个很好的学习挑战。我从 well-documented SOCKS5 example code 开始。

在示例中,Transfer 结构要求读取器和写入器的类型为 TcpStream。在我的代码中,这些需要是多态的,所以我从定义开始:

pub trait Pollable {
    fn poll_read(&self) -> Async<()>;
    fn poll_write(&self) -> Async<()>;
}

impl Pollable for TcpStream {
    fn poll_read(&self) -> Async<()> {
        tokio_core::net::TcpStream::poll_read(&self)
    }
    fn poll_write(&self) -> Async<()> {
        tokio_core::net::TcpStream::poll_write(&self)
    }
}

pub trait AsyncStream: tokio_io::AsyncRead + tokio_io::AsyncWrite + Pollable {}

impl<T> AsyncStream for T
where
    T: tokio_io::AsyncRead + tokio_io::AsyncWrite + Pollable,
{}

当我在第 510 行将 reader 的类型从 Rc&lt;TcpStream&gt; 切换到 Rc&lt;AsyncStream&gt; 时,编译器在第 598 行失败并出现此错误:

error[E0596]: cannot borrow immutable borrowed content as mutable
   --> src/transfer.rs:125:33
    |
125 |                 let n = try_nb!((&*self.reader).read(&mut buffer));
    |                                 ^^^^^^^^^^^^^^^ cannot borrow as mutable

忽略错误信息中的文件和行号;我正在将代码移动到多个文件中,但在其他方面与示例相同。

根据我在 Stack Overflow 其他地方找到的建议,我检查了类型。变更前&amp;*self.reader的类型为&amp;tokio_core::net::TcpStream;更改后,类型变为&amp;transfer::AsyncStream + 'static。当我从具体类型更改为特征时,我不知道为什么会出现 'static 生命周期...

为什么会这样?我该如何解决?

【问题讨论】:

  • 猜测:也许TcpStream 有一个名为read 的方法采用&amp;self,但AsyncStream(或其超特征之一)有一个名为read 的方法采用@987654338 @?

标签: rust


【解决方案1】:

tokio_core::net::TcpStream 实现 ReadAsyncRead for an immutable reference。你的特质没有。

&amp;*self.readerRc&lt;T&gt; 转换为&amp;T,用作read 方法的目标。

要修复它,您需要实现适当的 trait 以实现对您的 trait 的不可变引用,或者使用某种内部可变性。

另见:

【讨论】:

  • 谢谢!这似乎是我的问题。但是我担心我对这方面的了解还不够……不可变引用的特征是什么样的?
  • @TomKludy 我不确定我是否理解您的问题。我linked to an implementation of a trait for a reference,所以您似乎不太可能询问这种实现所需的语法。你能澄清一下你的问题吗?
  • 我尝试遵循您链接的模式并且可能更接近.. 但现在我收到错误:cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements 感谢您的耐心帮助!打算追这个一会……
猜你喜欢
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 1970-01-01
  • 2017-05-02
  • 2015-09-14
  • 1970-01-01
相关资源
最近更新 更多