erro de ferrugem “não é possível determinar um tipo para esta expressão”

StackOverflow https://stackoverflow.com//questions/9660086

  •  12-12-2019
  •  | 
  •  

Pergunta

eu escrevo um programa simples de ferrugem.

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

há algum erro nisso.

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

o que aconteceu nele?

Foi útil?

Solução

O compilador não conseguiu inferir o tipo que esta invocação de result::chain deveria retornar.É difícil ter certeza sem conhecer os tipos de connect e send, mas eu acho que é porque o corpo do seu bloco lambda está (provavelmente por engano) resultando no tipo nil.

O tipo de cada bloco em ferrugem é determinado por sua 'expressão final', e as expressões finais são criadas deixando o ponto-e-vírgula fora da instrução final.Presumivelmente, send retorna o result digite e é por isso que você está usando result::chain nele - de modo que o resultado de toda a expressão seja o resultado de send.Para fazer isso funcionar o send expressão não deve ser terminada por ponto e vírgula.Então seu bloco lambda retornará o resultado de send.

Algo assim pode funcionar melhor:

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

Quando a inferência de tipos falha, às vezes pode ser útil dividir as expressões em séries menores de instruções e inserir tipos explícitos até descobrir onde os tipos não estão correspondendo corretamente.Se eu acertasse algo assim e não conseguisse descobrir olhando por um tempo, então eu começaria a reescrevê-lo 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);
}

Claro, substituindo quaisquer tipos connect e send realmente usar.Em algum ponto do processo de desmontar tudo, você descobrirá onde você e o compilador discordam.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top