2015-07-22 10 views
7

Il tentativo di compilare il seguente,Perché i parametri di tipo non sono consentiti su questo tipo?

fn do_it() -> Result<i32, u32> { 
    Result::<i32, u32>::Ok(3) 
} 


fn main() { 
    println!("{}", do_it()); 
} 

risultati in:

./result_test.rs:2:14: 2:17 error: type parameters are not allowed on this type [E0109] 
./result_test.rs:2  Result::<i32, u32>::Ok(3) 
           ^~~ 

Perché i parametri di tipo non consentito su questo tipo?

Questo è un esempio minimo, il mio esempio del mondo reale è una macro cercando di restituire il seguente:

match $reader.$read_func() { 
    Ok(n) => Result::<$read_type, LocalReadError>::Ok(n), 
    Err(err) => Result::<$read_type, LocalReadError>::Err(
     LocalReadError::from(err) 
    ), 
} 

$read_func è una funzione, $read_type è il tipo di ritorno di quella funzione. (Se avessi un modo programmatico per farlo, lo farei: non so come, quindi è un argomento ...); così com'è, ottengo l'errore sopra riportato. Se rimuovo le specifiche dei parametri del generico, digita l'inteferenza che non riesce a capire il tipo. (?. Perché finisce con Result<_, LocalReadError> in un ramo della match, e Result<$read_type, _> nell'altra Io non sono davvero sicuro Dice:

error: unable to infer enough type information about `_`; type annotations or generic parameter binding required [E0282] 
    match $reader.$read_func() { 
        ^~~~~~~~~~~~ 

)

Nota: La domanda sul perché i parametri del tipo non sono ammessi viene data risposta di seguito. Risulta che questa non è la causa dell '"incapacità di dedurre informazioni di tipo sufficiente". (read_func è una funzione, nel mio caso, sto passando una funzione di modello, ma dimentico il modello arg, che non può essere dedotto.)

+0

Questo mi sembra straordinariamente un insetto. https://doc.rust-lang.org/nightly/error-index.html#E0109 mostra cosa dovrebbe fare. –

+1

come soluzione al tuo problema attuale ti suggerisco di cambiare la tua macro in '$ reader. $ Read_func(). Map_err (LocalReadError :: from)' –

+2

non sicuro se si tratta di un bug o se questo è effettivamente previsto, ma la sintassi che il lavoro sembra essere: 'Risultato :: Ok :: (3)'. [Box] (http://is.gd/xNUV9B) –

risposta

9

questa in realtà è un'incongruenza con enumerazione che è was discussed ma non considerata abbastanza importante bloccare 1.0.

La sintassi di lavoro per specificare i tipi è Result::Ok::<i32, u32>(3).

Un enum funziona come qualcosa tra un tipo (che andrebbe con la sintassi che si stava tentando di scrivere) e un namespace (e gli spazi dei nomi non accettano i parametri di tipo).

Per dimostrare come le enumerazioni sono come spazi dei nomi, è possibile scrivere:

use std::result::Result::*; 

fn main() { 
    println!("{:?}", Ok::<i32, u32>(3)); 
} 

Questo aspetto namespacing è una proprietà desiderabile di enumerazioni, ma spostando i parametri di tipo in cui si sarebbe intuitivamente pensare che dovrebbero essere renderebbe questo tipo di codice molto scomodo da scrivere.

Problemi correlati