Ber*_*rer 6 type-inference rust
我正在通过TCP编写聊天服务器作为学习项目.我受够了被修补WS箱子今天,但我遇到的一个问题.这是我编写的代码,修改了他们的服务器示例.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译它时,我收到一个错误:
error: the type of this value must be known in this context
--> src/main.rs:15:23
|
15 | message = message.trim();
| ^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我该如何解决这个问题?
move |message|隐藏message您在闭包之外声明的变量.所以在封闭中.. message据说是ws::Message......除非你这样做:
message = message.trim();
Run Code Online (Sandbox Code Playgroud)
编译器会"哦不!trim()?那不存在ws::Message"..所以现在它不知道该怎么做.
第一个修复涉及将trim()调用委托给发送消息的客户端.
修复是不对此闭包内的消息做出任何假设.如果你保留这个:
move |message|
Run Code Online (Sandbox Code Playgroud)
..但删除trim()调用,编译器愉快地推断它的类型ws::Message,并将构建:
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)
}
}
Run Code Online (Sandbox Code Playgroud)
这使您可以选择将trim()呼叫委派给客户端.
选项2涉及检查您收到的消息类型,并确保仅在文本时修剪它:
// 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)
}
Run Code Online (Sandbox Code Playgroud)
这可能比它需要的更冗长......但希望它能告诉你原始代码片段的实际问题.