【问题标题】:Rust: Reference to a generic parameter doesn't satisfy trait boundRust:对泛型参数的引用不满足 trait bound
【发布时间】:2021-01-26 21:52:47
【问题描述】:

我正在尝试用 Rust 编写一个简单的 TCP 客户端,询问用户是否希望他们的连接是 SSL。我正在尝试尽可能多地抽象代码,因此我正在尝试编写一个“communicate_with_server”函数,该函数应该能够接收SslStreamTcpStream

fn communicate_with_server<T: std::io::Read + std::io::Write>(mut stream: T) {
    let initial_message = format!("hello world");
    let mut buffer: Vec<u8> = Vec::new();
    let _bytes_written = stream.write_all(initial_message.as_bytes());
    let _flush = stream.flush();

    loop {
        let mut stream_reader = BufReader::new(&stream);
        stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
        // ... Wait for the server to respond and do some analysis on the response ...
    }
}

当我尝试编译这段代码时,我得到以下响应:

error[E0277]: the trait bound `&T: std::io::Read` is not satisfied
  --> src\main.rs:47:48
   |
47 |         let mut stream_reader = BufReader::new(&stream);
   |                                                -^^^^^^
   |                                                |
   |                                                the trait `std::io::Read` is not implemented for `&T`
   |                                                help: consider removing the leading `&`-reference
   |
   = note: required by `BufReader::<R>::new`

error[E0599]: no method named `read_until` found for struct `BufReader<&T>` in the current scope
  --> src\main.rs:49:23
   |
49 |         stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
   |                       ^^^^^^^^^^ method not found in `BufReader<&T>`
   | 

考虑到第一个错误,第二个错误是有道理的,但我不太确定为什么 &amp;T 没有实现 Read 特征。

【问题讨论】:

    标签: generics methods rust reference traits


    【解决方案1】:

    &amp;T 其中T: Read 不包含Read,因为许多Read trait 方法需要改变T,而&amp;T 是不可能的,即不可变参考T

    要解决您的问题,您应该将 可变 引用(即 &amp;mut stream)传递给 BufReader::new,如下所示:

    use std::io::{ Read, Write, BufReader, BufRead };
    
    fn communicate_with_server<T: Read + Write>(mut stream: T) {
        let initial_message = format!("hello world");
        let mut buffer: Vec<u8> = Vec::new();
        let _bytes_written = stream.write_all(initial_message.as_bytes());
        let _flush = stream.flush();
    
        loop {
            let mut stream_reader = BufReader::new(&mut stream);
            stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
            // ... Wait for the server to respond and do some analysis on the response ...
        }
    }
    

    playground

    【讨论】:

    • 有道理,谢谢!有没有办法可以创建一个可变引用而不是不可变引用?
    • 是的,您可以使用&amp;mut stream 创建一个可变引用,并且您可以将该可变引用传递给BufReader::new,因为&amp;mut T: Read 其中T: Read。我已经用这个细节更新了我的答案。
    • @fermi 如果我的回答解决了您的问题,请考虑通过单击答案分数下方的灰色复选标记来接受它,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2021-12-04
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多