2016-07-11 3 views
12

Ich schrieb Rust Fussel-Plugin, wenn ich festgestellt, dass Rust verschiedene Arten verwendet die dann (Block) und sonst (Expr) Teile einer if Aussage in beiden libsyntax::ast::ExprKind und librustc::hir::Expr_ darzustellen.Warum verwendet Rust's if-else AST verschiedene Arten für dann und sonst?

Ich brauche sie beide, um gemeinsame Typen zu haben.

Sollte ich nur eine explizite Übereinstimmung über hir::Expr_::ExprBlock verwenden, sonst könnte Teil etwas anderes sein, und ich muss einen schlaueren Vergleich machen?

Von the source:

// ... 
pub enum Expr_ { 
    // ... 
    /// An `if` block, with an optional else block 
    /// 
    /// `if expr { block } else { expr }` 
    ExprIf(P<Expr>, P<Block>, Option<P<Expr>>), 
    // ... 
} 
// ... 
+2

Ich denke, das liegt daran, dass Sie _have_ einen Block (also ein '{/ * code * /}') nach einem 'if' verwenden müssen, aber Sie können die Klammern nach einem 'else' weglassen. Sie können also 'if foo() {bar(); } else baz(); 'aber du kannst nicht schreiben' if foo() bar() else baz() '. – musicmatze

+1

@musicmatze das ist sehr falsch. Rust erlaubt ausdrücklich NICHT, die Zahnspange nach einer anderen wegzulassen. Sonst sind wir wieder in der Hölle baumelnd. –

+0

@ker ah, okay. Ich wusste das nicht, also danke, dass du mich korrigiert hast! – musicmatze

Antwort

7

Dies wird, so dass wir

if x { 
    foo(); 
} else if y { 
    bar(); 
} 

von

if x { 
    foo(); 
} else { // note the block 
    if y { 
     bar(); 
    } 
} 

Erstere ExprIf in dem Knoten der an anderen Expr hat, während die unterscheiden können Sekunde hat eine ExprBlock enthält als single ExprIf -ausdruck.

+5

Könnten Sie (Pseudo-) Codebeispiele geben, wie jeder der beiden Fälle als 'ExprIf' aussehen würde? – Shepmaster

+1

@Shempmaster, der erste ist 'ExprIf (_, Block (...), einige (ExprIf (...)))', und der zweite ist 'ExprIf (_, Block (...), einige (Block (..., AusdruckIf (...), ...))) '. – Cpud36

Verwandte Themen