重拾Kotlin(18)-运算符重载

作者: 业志陈 | 来源:发表于2019-06-05 23:19 被阅读14次

    一、运算符重载

    Kotlin 允许为类型提供预定义的操作符实现,这些操作符具有固定的符号表示(例如 + 和 * )和固定的优先级,通过操作符重载可以将操作符的行为映射到指定的方法。为实现这样的操作符,需要为类提供一个固定名字的成员函数或扩展函数,相应的重载操作符的函数需要用 operator 修饰符标记

    1.1、一元操作符

    操作符 函数
    +a a.unaryPlus()
    -a a.unaryMinus()
    !a a.not()
    a++ a.inc()
    a-- a.dec()

    1.2、二元操作符

    操作符 函数
    a + b a.plus(b)
    a - b a.minus(b)
    a * b a.times(b)
    a / b a.div(b)
    a % b a.rem(b)
    a..b a.rangeTo(b)
    a in b b.contains(a)
    a !in b !b.contains(a)
    a += b a.plusAssign(b)
    a -= b a.minusAssign(b)
    a *= b a.timesAssign(b)
    a /= b a.divAssign(b)
    a %= b a.remAssign(b)

    1.3、数组操作符

    操作符 函数
    a[i] a.get(i)
    a[i, j] a.get(i, j)
    a[i_1, ..., i_n] a.get(i_1, ..., i_n)
    a[i] = b a.set(i, b)
    a[i, j] = b a.set(i, j, b)
    a[i_1, ..., i_n] = b a.set(i_1, ..., i_n, b)

    1.4、等于操作符

    操作符 函数
    a == b a?.equals(b) ?: b === null
    a != b !(a?.equals(b) ?: b === null)

    相等操作符有一点不同,为了达到正确合适的相等检查做了更复杂的转换,因为要得到一个确切的函数结构比较,不仅仅是指定的名称

    方法必须要如下准确地被实现:

    operator fun equals(other: Any?): Boolean
    

    操作符 === 和 !== 用来做身份检查(它们分别是 Java 中的 == 和 != ),并且它们不能被重载

    1.5、比较操作符

    操作符 函数
    a > b a.compareTo(b) > 0
    a < b a.compareTo(b) < 0
    a >= b a.compareTo(b) >= 0
    a <= b a.compareTo(b) <= 0

    所有的比较都转换为对 compareTo 的调用,这个函数需要返回 Int 值

    1.6、函数调用

    方法 调用
    a() a.invoke()
    a(i) a.invoke(i)
    a(i, j) a.invoke(i, j)
    a(i_1, ..., i_n) a.invoke(i_1, ..., i_n)

    1.7、例子

    看几个例子

    data class Point(val x: Int, val y: Int) {
    
        //+Point
        operator fun unaryPlus() = Point(+x, +y)
    
        //Point++ / ++Point
        operator fun inc() = Point(x + 1, y + 1)
    
        //Point + Point
        operator fun plus(point: Point) = Point(x + point.x, y + point.y)
    
        //Point + Int
        operator fun plus(value: Int) = Point(x + value, y + value)
    
        //Point[index]
        operator fun get(index: Int): Int {
            return when (index) {
                0 -> x
                1 -> y
                else -> throw IndexOutOfBoundsException("无效索引")
            }
        }
    
        //Point(index)
        operator fun invoke(index: Int) = when (index) {
            0 -> x
            1 -> y
            else -> throw IndexOutOfBoundsException("无效索引")
        }
    
    }
    
    fun main(args: Array<String>) {
    
        //+Point(x=10, y=-20)  =  Point(x=10, y=-20)
        println("+${Point(10, -20)}  =  ${+Point(10, -20)}")
    
        //Point(x=10, y=-20)++  =  Point(x=10, y=-20)
        var point = Point(10, -20)
        println("${Point(10, -20)}++  =  ${point++}")
    
        //++Point(x=10, y=-20)  =  Point(x=11, y=-19)
        point = Point(10, -20)
        println("++${Point(10, -20)}  =  ${++point}")
    
        //Point(x=10, y=-20) + Point(x=10, y=-20)  =  Point(x=20, y=-40)
        println("${Point(10, -20)} + ${Point(10, -20)}  =  ${Point(10, -20) + Point(10, -20)}")
    
        //Point(x=10, y=-20) + 5  =  Point(x=15, y=-15)
        println("${Point(10, -20)} + ${5}  =  ${Point(10, -20) + 5}")
    
        point = Point(10, -20)
        //point[0] value is: 10
        println("point[0] value is: ${point[0]}")
        //point[1] value is: -20
        println("point[1] value is: ${point[1]}")
    
        //point(0) values is: 10
        println("point(0) values is: ${point(0)}")
    
    }
    

    重拾 Kotlin 系列文章目录: 重拾 Kotlin

    相关文章

      网友评论

        本文标题:重拾Kotlin(18)-运算符重载

        本文链接:https://www.haomeiwen.com/subject/khfwnqtx.html