Frage

Ich schreibe ein einfaches Rust-Programm.

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

Da ist ein Fehler drin.

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

Was ist darauf passiert?

War es hilfreich?

Lösung

Der Compiler konnte den Typ dieses Aufrufs nicht ableiten result::chain soll zurückkommen.Es ist schwer, es mit Sicherheit zu sagen, ohne die Arten zu kennen connect Und send, aber ich würde vermuten, dass es daran liegt, dass der Körper Ihres Lambda-Blocks (wahrscheinlich fälschlicherweise) zum Null-Typ führt.

Der Typ jedes Blocks in Rust wird durch seinen „Endausdruck“ bestimmt, und Endausdrücke werden erstellt, indem das Semikolon in der letzten Anweisung weggelassen wird.Vermutlich, send gibt die zurück result Typ und das ist, warum Sie verwenden result::chain darauf - so dass das Ergebnis des gesamten Ausdrucks das Ergebnis von ist send.Damit dies funktioniert send Ausdruck sollte nicht durch ein Semikolon abgeschlossen werden.Dann gibt Ihr Lambda-Block das Ergebnis von zurück send.

So etwas könnte besser funktionieren:

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

Wenn die Typinferenz fehlschlägt, kann es manchmal hilfreich sein, Ausdrücke in kleinere Folge von Anweisungen aufzuteilen und explizite Typen einzufügen, bis Sie herausgefunden haben, wo die Typen nicht richtig übereinstimmen.Wenn ich auf so etwas stoße und es durch langes Hinsehen nicht herausfinden könnte, dann würde ich anfangen, es so umzuschreiben

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

Natürlich alle Typen ersetzen connect Und send tatsächlich verwenden.Irgendwann im Prozess des Zerlegens werden Sie feststellen, wo Sie und der Compiler anderer Meinung sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top