Rust Type Inference Error

I am writing a chat server over TCP as a training project. Today I deal with ws , but I ran into a problem. This is the code I wrote modifying their server example .

extern crate ws; extern crate env_logger; use ws::listen; fn main() { // Setup logging env_logger::init().unwrap(); // Listen on an address and call the closure for each connection if let Err(error) = listen("127.0.0.1:3012", |out| { let mut message: String; // The handler needs to take ownership of out, so we use move move |message| { message = message.trim(); // Handle messages received on this connection println!("Server got message '{}'. ", message); // Use the out channel to send messages back out.send(message) } }) { // Inform the user of failure println!("Failed to create WebSocket due to {:?}", error); } } 

When I try to compile, I get an error message:

 error: the type of this value must be known in this context --> src/main.rs:15:23 | 15 | message = message.trim(); | ^^^^^^^^^^^^^^ 

Why is this happening? How can i fix this?

+6
source share
1 answer

move |message| shades the message variable that you specified outside of closure. So in closing .. message is called ws::Message ... except that you did this:

 message = message.trim(); 

The compiler goes "oh no! trim() ? This does not exist for ws::Message " .. and now it does not quite know what to do.

Option 1

The first fix involves delegating a trim() call to the client who sends the message.

The fix is ​​to not make any assumptions that the message is inside this closure. If you save this:

 move |message| 

.. but remove the trim() call, the compiler will happily pass it the ws::Message type and build:

 if let Err(error) = listen("127.0.0.1:3012", |out| { // The handler needs to take ownership of out, so we use move move |message| { // --- REMOVED trim() call --- // Handle messages received on this connection println!("Server got message '{}'. ", message); // Use the out channel to send messages back out.send(message) } } 

This gives you the ability to delegate a trim() call to the client.

Option 2

Option 2 includes checking the type of message you received and make sure that you cut it only if it is text:

 // The handler needs to take ownership of out, so we use move move |mut message: ws::Message| { // Only do it if the Message is text if message.is_text() { message = ws::Message::Text(message.as_text().unwrap().trim().into()); } // Handle messages received on this connection println!("Server got message '{}'. ", message); // Use the out channel to send messages back out.send(message) } 

This may be a little more verbose than necessary ... but hopefully it will show you what the actual problem is with your source code snippet.

+7
source

Source: https://habr.com/ru/post/1012919/


All Articles