我想使用异步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<TcpStream>
切换到Rc<AsyncStream>
时,编译器在第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的其他地方找到了建议,我检查了类型。在更改之前,&*self.reader
的类型为&tokio_core::net::TcpStream
;更改后,类型变为&transfer::AsyncStream + 'static
。当我从具体类型转变为特质时,我不知道为什么'static
生命进入...
为什么会这样?我该如何解决?
答案 0 :(得分:2)
tokio_core::net::TcpStream
实施Read
和AsyncRead
for an immutable reference。你的特质没有。
lastcol
将&*self.reader
转换为Rc<T>
,&T
用作read
方法的目标。
要解决此问题,您需要为特征的不可变引用实现适当的特征,或者使用某种内部可变性。
另见: