私が最近Pythonに触れると、X if C else Y
という形で、その可読性を理解することを学びました。Swift 3でのPythonスタイルの条件式
古典的なternary conditional operator ?:が最初の引数として条件を持つとき、割り当てはすべて選択に関するものだと感じます。複数の3項演算子を入れ子にしてみると醜いです...条件が最初の式の後に移動すると、関数の数学的定義のように感じます。私は時にはコードの明確さに役立つことがわかります。
code kataとして、私はSwiftでpythonスタイルの条件式を実装したかったのです。それは私に必要な構文を得ることができる唯一のツールがカスタム演算子であるように思えます。それらは記号で構成されていなければなりません。 Math symbols in UnicodeラベルTRUE ⊨
などの論理からdouble turnstileシンボルとバージョンを消さので、私は==|
と|!=
と一緒に行きました... ⊭
真実ではありません。これまでのところ、正しい優先度を見つけるためにしばらくのために戦った後、私はこれを持っている:
// Python-like conditional expression
struct CondExpr<T> {
let cond: Bool
let expr:() -> T
}
infix operator ==| : TernaryPrecedence // if/where
infix operator |!= : TernaryPrecedence // else
func ==|<T> (lhs: @autoclosure() -> T, rhs: CondExpr<T>) -> T {
return rhs.cond ? lhs() : rhs.expr()
}
func |!=<T> (lhs: Bool, rhs: @escaping @autoclosure() -> T) -> CondExpr<T> {
return CondExpr<T>(cond: lhs, expr: rhs)
}
私は結果が非常にswiftyまたは特にが読める見ていない知っているが、明るい側では、これらの事業者は、作業式が複数行にまたがっても
let e = // is 12 (5 + 7)
1 + 3 ==| false |!=
5 + 7 ==| true |!=
19 + 23
あなたが空白で創造的な取得すると、それも少しニシキヘビを感じている:
let included =
Set(filters) ==| !filters.isEmpty |!=
Set(precommitTests.keys) ==| onlyPrecommit |!=
Set(allTests.map { $0.key })
私は二autoclosureがエスケープされなければならないことを好きではありません。 Nate Cook's answer about custom ternary operators in Swift 2は、もはやSwift 3にはないカリングシンタックスを使用していました...そして、私はそれも技術的にもエスケープクロージャであったと思います。
閉鎖をエスケープしないでこの作業を行う方法はありますか? それは問題ですか?たぶんSwiftコンパイラはコンパイル時にこの問題を解決するのに十分なほどスマートなので、実行時の影響はありません。
ニース。おそらく、その2番目の関数本体をもっときれいにすることができます:https://gist.github.com/woolsweater/4da0dc0bb348fb40a2becb1aec9a2890 –
フィードバックをいただきありがとうございます。私は私の答えをクリーンアップします。 –
最初の関数本体は 'return rhs ?? lhs() ' –