ошибка rust “не удается определить тип для этого выражения”
-
12-12-2019 - |
Вопрос
я пишу простую программу 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
что на нем произошло?
Решение
Компилятору не удалось определить тип, который этот вызов result::chain
предполагается, что он вернется.Трудно сказать наверняка, не зная типов connect
и send
, но я бы предположил, что это потому, что тело вашего лямбда-блока (вероятно, ошибочно) приводит к типу nil.
Тип каждого блока в rust определяется его "конечным выражением", а конечные выражения создаются путем удаления точки с запятой из конечного оператора.Предположительно, send
возвращает значение result
введите, и именно поэтому вы используете result::chain
на нем - так, чтобы результат всего выражения был результатом send
.Чтобы заставить это работать, send
выражение не должно заканчиваться точкой с запятой.Тогда ваш лямбда-блок вернет результат 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);
}
Конечно, заменяя любые типы connect
и send
на самом деле используйте.В какой-то момент в процессе разбора всего на части вы обнаружите, в чем вы с компилятором расходитесь во мнениях.