当前位置: 首页 > 知识库问答 >
问题:

Rust类型推断错误

关飞翔
2023-03-14

作为一个学习项目,我正在编写一个通过TCP的聊天服务器。我今天一直在修补ws crate,但我遇到了一个问题。这是我编写的代码,修改了他们的服务器示例。

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();
   |                       ^^^^^^^^^^^^^^

为什么会这样?我怎样才能解决这个问题?

共有1个答案

笪昌翰
2023-03-14

move|message|将您在闭包外部声明的消息变量隐藏起来。因此,在闭包中,<code>消息</code>被称为<code>ws::message</code>…除非您这样做:

message = message.trim();

编译器会说“哦不!< code>trim()?对于< code>ws::Message,它不存在..所以现在它不知道该做什么。

第一个修复是将< code>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涉及检查您收到的消息类型,并确保仅当消息为文本时才对其进行修剪:

// 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)
}

这也许比它需要的要详细一些。但希望它能向您展示原始代码片段的实际问题。

 类似资料:
  • 我正在尝试编写一个android静态编程语言应用程序,但我得到了以下错误。我哪里出错了? 这是我如何声明我的HashMap: 错误: 类型推断失败。没有足够的信息来推断构造函数HashMap中的参数K。请明确说明

  • 主要内容:1 Java8 类型推断的介绍,2 Java8 类型推断的案例1,3 Java8 类型推断的案例21 Java8 类型推断的介绍 类型推断是Java的一项功能,它使编译器可以查看每个方法调用和相应的声明以确定参数的类型。 Java在Java 8中提供了类型推断的改进版本。 1.1 Java8以前 在下面的声明中,我们在一侧提到了arraylist的类型。这种方法是在Java 7中引入的。在这里,您可以将第二面留为<>,并且编译器将通过引用变量的类型来推断其类型。 1.2 Java8以后

  • TypeScript 类型检查机制包含三个部分: 类型推断 类型保护 类型兼容性 本节介绍其中的类型推断,类型推断主要用于那些没有明确指出类型的地方帮助确定和提供类型,这是 TypeScript 的一种能力。 类型推断是有方向的,要注意区分从左向右和从右向左两种推断的不同应用。 1. 慕课解释 类型推断的含义是不需要指定变量类型或函数的返回值类型,TypeScript 可以根据一些简单的规则推断其

  • 01 模板类型推断机制 auto 推断的基础是模板类型推断机制,但部分特殊情况下,模板推断机制不适用于 auto 模板的形式可以看成如下伪代码 template<typename T> void f(ParamType x); // ParamType 即 x 的类型 调用可看成 f(expr); 编译期间,编译器用 expr 推断 T 和 ParamType,实际上两者通常不一致,比如 te

  • 为什么可以推断闭包表达式的参数类型和返回类型,而不是rust中的函数?