How to customize ternary operators in Swift

前端 未结 3 633
梦如初夏
梦如初夏 2020-12-16 01:30

I know how to customize binary operators, like this

infix operator ** { associativity left precedence 170 }
func ** (left: Double, right: Double) -> Doubl         


        
3条回答
  •  感动是毒
    2020-12-16 02:31

    You can actually do this by declaring two separate operators that work together and using a curried function for one of the operators.

    Let's declare a ternary operator x +- y +|- z that will check the sign of the initial value x, and then return the second value y if the sign is zero or positive and the final value z if the sign is negative. That is, we should be able to write:

    let sign = -5 +- "non-negative" +|- "negative"
    // sign is now "negative"
    

    We'll start by declaring the two operators. The important part is to have higher precedence on the second operator - we'll evaluate that part first and return a function:

    infix operator +- { precedence 60 }
    infix operator +|- { precedence 70 }
    

    Then define the functions - we'll define the second first:

    func +|-(lhs: @autoclosure () -> T, rhs: @autoclosure () -> T)(left: Bool) -> T {
        return left ? lhs() : rhs()
    }
    

    The important part here is that this function is curried -- if you only call it with the first two parameters, instead of returning a T value, it returns a (left: Bool) -> T function. That becomes the second parameter of the function for our first operator:

    func +-(lhs: I, rhs: (left: Bool) -> T) -> T {
        return rhs(left: lhs >= 0)
    }
    

    And now we can use our "ternary" operator, like this:

    for i in -1...1 {
        let sign = i +- "" +|- "-"
        println("\(i): '\(sign)'")
    }
    // -1: '-'
    // 0: ''
    // 1: ''
    

    Note: I wrote a blog post on this subject with another example.

提交回复
热议问题