Question

i write a simple rust program.

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

there is some error on it.

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

what happened on it?

Was it helpful?

Solution

The compiler has failed to infer type that this invocation of result::chain is supposed to return. It's hard to tell for sure without knowing the types of connect and send, but I would guess that it's because the body of your lambda block is (probably mistakenly) resulting in the nil type.

The type of every block in rust is determined by it's 'tail expression', and tail expressions are created by leaving the semicolon off of the final statement. Presumably, send returns the result type and that's why you are using result::chain on it - so that the result of the entire expression is the result of send. To make this work the send expression should not be terminated by a semicolon. Then your lambda block will return the result of send.

Something like this may work better:

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

When type inference fails it can sometimes be helpful to breakdown expressions into smaller series of statements and insert explicit types until you figure out where the types are not matching up correctly. If I hit something like this and couldn't figure it out by eyeballing it for a while, then I would begin rewriting it like

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

Of course substituting whatever types connect and send actually use. At some point in the process of pulling everything apart you will find out where you and the compiler disagree.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top