Rust 类型推断错误
Rust Type Inference Error
我正在通过 TCP 编写聊天服务器作为学习项目。我一直在修补 ws crate today, but I've come across an issue. 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);
}
}
当我尝试编译它时出现错误:
error: the type of this value must be known in this context
--> src/main.rs:15:23
|
15 | message = message.trim();
| ^^^^^^^^^^^^^^
为什么会这样?我该如何解决这个问题?
move |message|
隐藏了您在闭包外声明的 message
变量。所以在闭包中.. message
据说是 ws::Message
...除非你这样做了:
message = message.trim();
编译器 "oh no! trim()
? That doesn't exist for ws::Message
".. 所以现在它不太知道要做什么。
选项 1
第一个修复涉及将 trim()
调用委托给发送消息的客户端。
解决方法是不对该闭包中的消息内容做任何假设。如果你保留这个:
move |message|
..但删除 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)
}
}
这让您可以选择将 trim()
调用委托给客户端。
选项 2
选项 2 涉及检查您收到的消息类型,并确保您 trim 只有当它是文本时:
// 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)
}
这可能比需要的更冗长..但希望它能告诉您原始代码片段的实际问题是什么。
我正在通过 TCP 编写聊天服务器作为学习项目。我一直在修补 ws crate today, but I've come across an issue. 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);
}
}
当我尝试编译它时出现错误:
error: the type of this value must be known in this context
--> src/main.rs:15:23
|
15 | message = message.trim();
| ^^^^^^^^^^^^^^
为什么会这样?我该如何解决这个问题?
move |message|
隐藏了您在闭包外声明的 message
变量。所以在闭包中.. message
据说是 ws::Message
...除非你这样做了:
message = message.trim();
编译器 "oh no! trim()
? That doesn't exist for ws::Message
".. 所以现在它不太知道要做什么。
选项 1
第一个修复涉及将 trim()
调用委托给发送消息的客户端。
解决方法是不对该闭包中的消息内容做任何假设。如果你保留这个:
move |message|
..但删除 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)
}
}
这让您可以选择将 trim()
调用委托给客户端。
选项 2
选项 2 涉及检查您收到的消息类型,并确保您 trim 只有当它是文本时:
// 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)
}
这可能比需要的更冗长..但希望它能告诉您原始代码片段的实际问题是什么。