2017-04-06 4 views
0

私はSwiftには新しく、Swayパーサーを出力するためにjayパーサジェネレータを移植する過程にあります。パーサースケルトンファイルでは、条件式内の代入式の結果を使用する構造体が見つかりました。例えば。 (yyN += yyErrorCode) >= 0表現Swift 3のコンディションの中で代入式を扱うきれいな方法はありますか?

特に...

if ((yyN = yySindex[yyStates[yyTop]]) != 0 && 
    (yyN += yyErrorCode) >= 0 && 
    yyN < yyTable.Length && 
    yyCheck[yyN] == yyErrorCode) { ... } 

注スウィフトは、代入式が値を返すことはできませんのでスウィフトにこの型の構築物をコード化するための効率的な方法はありますか?

+0

これが意図的に禁止されている:それはyyThis yyMuch yyMore yyReadableようclusterfucksになります。 – Alexander

答えて

0

はい:

yyN = yySindex[yyStates[yyTop]] 
if yyN != 0 { 
    yyN += yyErrorCode 
    if yyN >= 0 && yyN < yyTable.Length && yyCheck[yyN] == yyErrorCode { 
     // … 
    } 
} 
1

スウィフトは、代入式が値を返すことはできませんのでスウィフトにこの型の構築物をコード化するための効率的な方法は ありますか?

はい:条件の割り当てを分割し、小さな要素に分割します(例:@tuple_cat:s answerを参照)。


それの楽しみのために

を(これをしないでください)、およびスウィフトのいくつかの技術的な可能性を簡単に見ため。 Swift を使用して、上記のように大きくクラスタ化された条件付き評価をエミュレートすることができます。 (恐ろしく非クリーンな方法で)あなたの例をSwiftifyするには、さらに非可読性を盛り上げるためにクロージャを-returningインラインyyN -capturingとBoolを使用することができます。

if ({_ in yyN = yySindex[yyStates[yyTop]]; return yyN != 0}()) && 
    ({_ in yyN += yyErrorCode; return yyN != 0}()) && 
    yyN < yyTable.Length && 
    yyCheck[yyN] == yyErrorCode { 
    /* ... */ 
} 

スウィフトはまた、独自の演算子を定義することができます、デフォルトのバージョン(副作用)を単に呼び出す代入演算子を組み立てることができますが、代入文の結果として割り当てられた値を返します。例えば。場合yyNタイプIntは次のとおりです。

// some C++ style assignment operators 
infix operator ^=: AssignmentPrecedence 
infix operator ^+=: AssignmentPrecedence 
extension Int { 
    static func ^= (lhs: inout Int, rhs: Int) -> Int { 
     lhs = rhs 
     return rhs 
    } 
    static func ^+= (lhs: inout Int, rhs: Int) -> Int { 
     lhs += rhs 
     return lhs 
    } 
} 

if ((yyN ^= yySindex[yyStates[yyTop]]) != 0 && 
    (yyN ^+= yyErrorCode) >= 0 && 
    yyN < yyTable.Length && 
    yyCheck[yyN] == yyErrorCode) { 
    /* ... */ 
} 
関連する問題