Still struggling with the Rust mind shift, now I have this use case - one configuration for a multi-threaded TcpListener
:
use std::net::{TcpListener, TcpStream, ToSocketAddrs};
use std::thread;
fn main() {
serve("127.0.0.1:3333", Configuration { do_something: true });
}
//#[derive(Copy, Clone)]
pub struct Configuration {
pub do_something: bool,
}
pub fn serve<A: ToSocketAddrs>(addr: A, conf: Configuration) {
let listener = TcpListener::bind(addr).expect("bind failed");
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || {
handle_client(stream, &conf);
});
}
Err(e) => {
println!("Connection failed: {}", e);
}
}
}
}
fn handle_client(stream: TcpStream, conf: &Configuration) {
if conf.do_something {
//stream....
}
}
I'm happy that the TcpStream
is consumed by handle_client
, that's it's purpose, but why does Configuration
have to be copied for each thread? I'd like to have just one copy and share an immutable reference with all threads. Is that possible? Or perhaps I'm missing the point.
Why do I need the Copy
and Clone
traits if I'm passing Configuration
by reference? This confused me a good deal:
error[E0382]: capture of moved value: `conf`
--> src/main.rs:19:64
|
19 | thread::spawn(move || { handle_client(stream, &conf); });
| ------- ^^^^ value captured here after move
| |
| value moved (into closure) here
|
= note: move occurs because `conf` has type `Configuration`, which does not implement the `Copy` trait