error de oxidación "no se puede determinar un tipo para esta expresión"
-
12-12-2019 - |
Pregunta
Escribo un programa de óxido simple.
fn main(){
let port = 80;
result::chain(connect("localhost", port as u16)) {|s|
send(s,str::bytes("hello world"));
};
hay algún error en él.
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
¿Qué pasó con eso?
Solución
El compilador no ha podido inferir el tipo de que esta invocación de result::chain
se supone que regresará.Es difícil saberlo con certeza sin conocer los tipos de connect
y send
, pero supongo que se debe a que el cuerpo de su bloque lambda (probablemente por error) da como resultado el tipo nulo.
El tipo de cada bloque en Rust está determinado por su 'expresión de cola', y las expresiones de cola se crean dejando el punto y coma fuera de la declaración final.Presumiblemente, send
devuelve el result
escribe y es por eso que estás usando result::chain
en él, de modo que el resultado de la expresión completa sea el resultado de send
.Para que esto funcione send
La expresión no debe terminar con un punto y coma.Entonces su bloque lambda devolverá el resultado de send
.
Algo como esto puede funcionar mejor:
fn main(){
let port = 80;
result::chain(connect("localhost", port as u16)) {|s|
send(s,str::bytes("hello world")) // <- no semicolon
};
}
Cuando la inferencia de tipos falla, a veces puede resultar útil dividir las expresiones en series más pequeñas de declaraciones e insertar tipos explícitos hasta que descubra dónde los tipos no coinciden correctamente.Si llego a algo como esto y no puedo entenderlo observándolo por un tiempo, entonces comenzaría a reescribirlo como
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);
}
Por supuesto sustituyendo cualquier tipo connect
y send
realmente uso.En algún momento del proceso de separar todo, descubrirá en qué no están de acuerdo usted y el compilador.