Swift3で後置if/unlessを行うカスタム演算子を定義してみます。
<?がif、<!?がunlessです。
precedencegroup PostPositionCondition {
associativity: left
higherThan: AssignmentPrecedence
lowerThan: TernaryPrecedence
}
infix operator <?: PostPositionCondition
infix operator <!?: PostPositionCondition
func <?<T>(_ statement: @autoclosure () -> T, _ condition: @autoclosure () -> Bool) -> T? {
return condition() ? statement() : .none
}
func <!?<T>(_ statement: @autoclosure () -> T, _ condition: @autoclosure () -> Bool) -> T? {
return condition() ? .none : statement()
}
使ってみましょう。
func cond(_ flag: Bool) -> Bool {
return flag
}
let result_if = 1 + 1 <? cond(true) // 2
let result_unless1 = 1 + 1 <!? cond(true) // nil
let result_unless2 = 1 + 1 <!? false // 2
print("if") <? cond(true) // "if"が出力される
print("unless") <!? cond(true) // 何も出力されない
print("if_if") <? true <? false // 何も出力されない
以上のようになります。autoclosureにより、条件に当てはまらない場合は前項は実行されていません。
ただし、throwと一緒には利用できません。<!?がthrowと一緒に使えると良かったのですが。