-1

我写了一个简单的 rust 程序。

fn main(){
    let port = 80;
    result::chain(connect("localhost", port as u16)) {|s|
    send(s,str::bytes("hello world"));
};

上面有一些错误。

macmatoMacBook-Air-2:rust-http kula$ rustc http.rs
http.rs:40:4: 40:52 error: cannot determine a type for this expression
http.rs:40     result::chain(connect("localhost", port as u16)) {|s|
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous errors

发生了什么?

4

1 回答 1

4

编译器未能推断出此调用result::chain应该返回的类型。connect如果不知道and的类型,很难确定send,但我猜这是因为你的 lambda 块的主体(可能错误地)导致 nil 类型。

rust 中每个块的类型由它的“尾部表达式”确定,尾部表达式是通过将分号从最终语句中去掉来创建的。大概,send返回result类型,这就是你使用result::chain它的原因 - 这样整个表达式的结果就是send. 为了完成这项工作,send表达式不应以分号结尾。然后你的 lambda 块将返回send.

这样的事情可能会更好:

fn main(){
    let port = 80;
    result::chain(connect("localhost", port as u16)) {|s|
        send(s,str::bytes("hello world")) // <- no semicolon
    };
}

当类型推断失败时,有时将表达式分解为更小的语句系列并插入显式类型,直到找出类型不正确匹配的位置有时会很有帮助。如果我碰到这样的东西并且通过一段时间的眼球无法弄清楚它,那么我将开始重写它

fn main(){
    let port = 80;
    let conn_result: result::t<connection, str> = connect("localhost", port as u16);
    let send_fn =  fn@(s: connection) -> result::t<str, str> {
        let send_result: result<str, str> = send(s,str::bytes("hello world"));
        ret send_result;
    };
    let res: result<str, str> = result::chain(conn_result, send_fn);
}

当然可以替换任何类型connectsend实际使用。在将所有内容分开的过程中的某个时刻,您会发现您和编译器存在分歧的地方。

于 2012-03-12T00:11:22.247 回答