2015-07-22 14 views
7

Próba skompilować następujące,Dlaczego parametry typu nie są dozwolone w tym typie?

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


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

skutkuje:

./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) 
           ^~~ 

Dlaczego parametry typu niedozwolone na tego typu?

Jest to minimalny przykład, mój przykład rzeczywistym świecie jest makro próbuje powrócić następujące:

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

$read_func jest funkcją, $read_type jest typ zwracany tej funkcji. (Gdybym miał programowy sposób, aby to uzyskać, zrobiłbym to, nie wiem jak, więc to jest arg ...); tak jak jest, otrzymuję powyższy błąd. Jeśli usunę specyfikację parametrów generycznych, wpisz inteference narzeka, że ​​nie może określić typu. (?. Ponieważ kończy się Result<_, LocalReadError> w jednym oddziale match i Result<$read_type, _> w drugiej nie jestem pewien, on mówi:

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

)

Uwaga: pytanie, dlaczego parametry typu są niedozwolone, odpowiada poniżej. Okazuje się, że nie jest to przyczyną "braku możliwości określenia wystarczającej informacji o typie". (read_func jest funkcją, w moim przypadku, przechodzę do funkcji szablonowej, ale zapominając o argumencie szablonu, którego nie można wywnioskować.)

+0

Wygląda mi to jak błąd. https://doc.rust-lang.org/nightly/error-index.html#E0109 pokazuje, co powinien robić. –

+1

jako obejście twojego aktualnego problemu Proponuję zmienić twoje makro na '$ reader. $ Read_func(). Map_err (LocalReadError :: from)' –

+2

nie wiem, czy to błąd, czy jest to rzeczywiście oczekiwane, ale składnia, która wygląda na to, że: "Wynik: Ok :: (3)". [Kojec] (http://is.gd/xNUV9B) –

Odpowiedz

9

jest to w rzeczywistości niezgodność z wyliczeniami, która was discussed, ale nie jest uważana za wystarczająco ważną blokować 1.0.

Robocza składnia do określania typów to Result::Ok::<i32, u32>(3).

Wyliczenie działa jak coś pomiędzy typem (który pasowałby do składni, którą próbujesz napisać) i przestrzenią nazw (a przestrzenie nazw nie akceptują parametrów typu).

Aby zademonstrować jak teksty stałe są jak przestrzenie nazw, można napisać:

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

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

Ten aspekt Przestrzenie nazw jest pożądaną właściwością teksty stałe, ale przesuwając parametry typu, gdzie można by intuicyjnie, że powinny one być uczyniłoby ten typ kod bardzo niezręczny do napisania.