Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
731 views
in Technique[技术] by (71.8m points)

methods - Rust: Reference to a generic parameter doesn't satisfy trait bound

I'm trying to write a simple TCP client in Rust that asks the user whether or not they want their connection to be SSL. I'm trying to abstract as much code out as possible, so I'm attempting to write a "communicate_with_server" function that should be able to take in a SslStream or a TcpStream.

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'
', &mut buffer).expect("Reading into buffer failed");
        // ... Wait for the server to respond and do some analysis on the response ...
    }
}

When I try to compile this code, I get the following response:

error[E0277]: the trait bound `&T: std::io::Read` is not satisfied
  --> srcmain.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
  --> srcmain.rs:49:23
   |
49 |         stream_reader.read_until(b'
', &mut buffer).expect("Reading into buffer failed");
   |                       ^^^^^^^^^^ method not found in `BufReader<&T>`
   | 

The second error makes sense given the first, but I'm not quite sure why &T doesn't implement the Read trait.

question from:https://stackoverflow.com/questions/65909797/rust-reference-to-a-generic-parameter-doesnt-satisfy-trait-bound

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

&T where T: Read does not impl Read because many of the Read trait methods require mutating T which is not possible with a &T, i.e. an immutable reference to T.

To fix your issue you should instead pass a mutable reference, i.e. &mut stream, to BufReader::new like this:

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'
', &mut buffer).expect("Reading into buffer failed");
        // ... Wait for the server to respond and do some analysis on the response ...
    }
}

playground


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...