2015-07-22 9 views
7

Der Versuch, die folgenden zu kompilieren,Warum sind Typparameter bei diesem Typ nicht erlaubt?

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


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

Ergebnisse 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) 
           ^~~ 

Warum Typ-Parameter sind nicht auf diese Art erlaubt?

Dies ist ein minimales Beispiel, ist mein reales Beispiel ein Makro folgenden versuchen zurückzukehren:

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

$read_func ist eine Funktion, $read_type ist der Rückgabetyp dieser Funktion. (Wenn ich einen programmatischen Weg dafür hätte, würde ich das tun; ich weiß nicht wie, also ist es ein Arg ...); wie es ist, bekomme ich den obigen Fehler. Wenn ich die Spezifikation der generischen Parameter entferne, tippe interference beschwert, dass es den Typ nicht herausfinden kann. (?. Weil es mit Result<_, LocalReadError> in einem Zweig der match endet, und Result<$read_type, _> im anderen Ich bin nicht wirklich sicher, es sagt:

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

)

Hinweis: Die Frage, warum Typparameter sind nicht erlaubt, wird unten beantwortet. Es stellt sich heraus, dass dies nicht die Ursache dafür ist, dass "nicht genügend Typinformationen abgeleitet werden können". (read_func ist eine Funktion, in meinem Fall überlasse ich eine Template-Funktion, aber vergessen die Vorlage arg, die nicht abgeleitet werden kann.)

+0

Das sieht für mich bemerkenswert wie ein Käfer aus. https://doc.rust-lang.org/nightly/error-index.html#E0109 zeigt, was es tun soll. –

+1

als Workaround zu Ihrem eigentlichen Problem Ich schlage vor, Ihr Makro zu '$ reader zu ändern. $ Read_func(). Map_err (LocalReadError :: from)' –

+2

nicht sicher, ob es ein Fehler ist oder ob dies tatsächlich erwartet wird, aber die Syntax Arbeiten scheint zu sein: 'Ergebnis :: Ok :: (3)'. [Laufsteg] (http://is.gd/xNUV9B) –

Antwort

9

Dies ist eigentlich eine Inkonsistenz mit Enums, dass was discussed aber nicht als wichtig genug um 1.0 zu blockieren.

Die Arbeitssyntax zur Angabe von Typen lautet Result::Ok::<i32, u32>(3).

Ein Enum funktioniert wie etwas zwischen einem Typ (der mit der zu schreibenden Syntax passen würde) und einem Namespace (und Namespaces akzeptieren keine Typparameter).

Um zu zeigen, wie Aufzählungen wie Namespaces sind, können Sie schreiben:

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

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

Dieser Namespacing Aspekt ist eine wünschenswerte Eigenschaft von Aufzählungen, aber Parameter Typ bewegen, wo man würde sie intuitiv denken, sollte diese Art der würde sein Code sehr umständlich zu schreiben.

Verwandte Themen