2017-03-23 2 views
0

Es scheint, dass ? and catch have been accepted into Rust, aber ich bin nicht in der Lage richtig zu nutzen:Wie zu verwenden? und in Rust fangen?

let x = catch { 
    1 
} 

Ich denke, das mir Ok(1) geben soll. Stattdessen erhalte ich den Fehler:

error: expected identifier, found `1` 
    --> src/main.rs:15:9 
    | 
15 |   1 
    |  ^

Wird diese Syntax in Rust noch nicht unterstützt, oder gibt es ein Problem mit meinem Code?

+0

Eigentlich nur der Fragezeichen-Operator ist in der Sprache gerade jetzt. Dieser Link verweist lediglich auf einen RFC. –

+1

Die Chancen stehen gut, dass die meisten Leute sowieso nicht 'catch' verwenden wollen. Es ist meiner Meinung nach kein gebräuchliches Ding. – Shepmaster

+0

Ich würde vorschlagen, dass Sie Alecs Antwort anstelle von mir akzeptieren: zu erklären, warum die Fehlermeldung cool ist und alles, aber zu erklären, wie Sie 'catch' tatsächlich verwenden, ist wahrscheinlich nützlicher :) Kein Druck obwohl, und Sie sind frei, jede Antwort zu akzeptieren du möchtest. –

Antwort

5

TL; DR: Der RFC ist akzeptiert, aber Ihre Syntax ist leicht aus (leider) und das Feature ist noch gated.

Siehe Alecs ausgezeichnete Antwort auf, wie man tatsächlich catch verwendet.


Ich ermutige Sie, die voll Fehlerprotokoll zu lesen:

error: expected identifier, found `1` 
--> <anon>:2:21 
    | 
2 |  let x = catch { 1 }; 
    |     ^

error[E0422]: cannot find struct, variant or union type `catch` in this scope 
--> <anon>:2:13 
    | 
2 |  let x = catch { 1 }; 
    |    ^^^^^ not found in this scope 

error: aborting due to 2 previous errors 

Der Schlüssel ist in der zweiten Fehlermeldung:

cannot find struct, variant or union type catch in this scope

, die uns wirklich, dass catch wissen lässt, wird vom Compiler nicht als Schlüsselwort erkannt.

Da catch wie jedes normale Wort aussieht, versucht der Compiler, dies als struct oder enum zu analysieren. Tatsächlich ein struct oder enum die Syntax für den Aufbau ist:

struct X { name: i32 } 

let x = X { name: 1 }; 

Daher ist der Compiler sieht <identifier> { und erwartet, dass es durch eine Liste von <identifier>: <expression> folgen. Es liest 1, die keine Kennung ist, und meldet den Fehler 1 ist kein Bezeichner.

+0

Die TL; DR ist (teilweise) falsch. Siehe meine Antwort. – Alec

5

Das wird sehr dumm klingen, weil es irgendwie ist. Sie benötigen Grundsätzlich

#![feature(catch_expr)] 

fn main() { 
    let x = do catch { 
     1 
    }; 
} 

haben, catch, wie default und union kann kein Schlüsselwort vorgenommen werden, ohne die Kompatibilität zu brechen rückwärts. Da Rust versucht hat, zu garantieren, dass jeder Code auf 1.x immer noch auf 1.y funktioniert, ging es bei der Einführung von default, union und jetzt catch in die Grammatik darum, die Konflikte herauszufinden. Für union und default gibt es keine - Bezeichner werden in diesen Positionen nie erwartet.

Für catch kann catch { 1 } auch als ein Strukturliteral interpretiert werden. Es sei denn, Sie benötigen do (ein reserviertes Schlüsselwort) treten vor catch auf - dann gibt es keine Mehrdeutigkeit. Ja, das ist hässlich und jeder weiß es.

Hoffentlich gehen diese Alpträume weg, wenn 2.0 kommt und wir die Rückwärtskompatibilität brechen können.Zitat aus der :

There's a growing list of other syntax we would ultimately like to repurpose in this way, but we generally avoid breaking the ability to run code that worked on 1.x on 1.y where y > x except in cases where the code was exploiting a compiler bug or was just a terrifically rare construction. Our stability guarantees demand we wait until 2.0 for most of these.

+5

* wenn 2.0 kommt * - es gibt keine Pläne für eine Rust 2.0, und man könnte sogar sagen, es gibt * Anti-Pläne * - niemand ist aufgeregt, rückwärts Kompatibilität zu brechen aufgrund der Zurückhaltung in vielen der Domänen zu aktualisieren Rost Ziele. – Shepmaster

+6

@Shempmaster Ich hoffe, du liegst falsch. :) TBH, für viele dieser Änderungen bricht wirklich sehr wenig Code in der Wildnis - das Problem ist, dass man sich Code vorstellen kann, der _brechen_ könnte. "Union" zu einem Schlüsselwort zu machen, wäre auf lange Sicht wahrscheinlich eine sehr gute Idee - aber es sollte ein sehr langsamer Prozess sein. Zuerst kommen die Warnungen "' union' wird ein Schlüsselwort, benutze es nicht als Variable ", dann kann ein Fehler mit einem Flag, dann endlich ein schwerer Fehler behoben werden. Sonst wird Rusts Grammatik genauso wie C++ funktionieren. – Alec

Verwandte Themen