美文网首页
运算符和表达式

运算符和表达式

作者: 凌寒天下独自舞 | 来源:发表于2018-09-26 22:04 被阅读0次

    Kotlin 语言提供了一系列功能丰富的运算符,这些运算符包括所有的算术运算符,还包括比较运算符、逻辑运算符、区间运算符和位运算符等。Kotlin 基本支持 Java 的全部运算符(可能有些在写法上存在差异), Kotlin不支持三目运算符(因为 Kotlin可用 if表达式代替三目运算符),Kotlin 的位运算符与 Java 的位运算符也略有区别 。Kotlin的运算符都是以方法形式来实现的,这些运算符都具有特定的符号(如“+”或“*”)和固定的优先级。

    与java相同的运算符

    单目前缀运算符

    单目前缀运算符有+、-、!这三个 。 它们对应的固定方法如表所示:

    运算符 对应的方法
    +a a.unaryPlus()
    -a a.unaryMinus()
    !a a.not()
    fun main(args: Array<String>) {
        var a :Int =10
        var b = -a
        println(b)
        println(a.unaryMinus())
    
        var c=+a
        println(c)
        println(a.unaryPlus())
    
        var boo = true
        var boo1 = !boo
        println(boo1)
        println(boo.not())
    
    }
    

    从上面的代码可以看出,-a与 a.unaryMinus()的效果是完全一样的;因此,以后读者在查阅 API时发现某个类有 unaryPlus()、unaryMinus()、 not()方法,那就说明可对该类的实例使用单目前缀运算符+、 -、!进行运算。

    自加和自减运算符

    自加(++)和自减(--)运算符及对应的固定方法如表所示。

    运算符 对应的方法
    a++ a.inc()
    a-- a.dec()

    由于++、--放在变量前后是有区别的,因此自加和自减运算符对应的 inc()和 dec()两个方法还不完全等同于 a++、 a--。

    双目运算符

    运算符 对应的方法
    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)

    in 和!in 运算符

    运算符 对应的方法
    a in b b.contains(a)
    a !in b !b.minus(a)

    索引访问运算符

    运算符 对应的方法
    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)

    调用运算符

    运算符 对应的方法
    a() a.invoke()
    a(b1,...) a.invoke(b1,...)

    通过上表可以发现调用运算符其实就是省略了 invoke方法名

    
    fun main(args: Array<String>) {
        var a :String ="ssss"
        //通过反射获取string类的length()方法
        val mtd = a.javaClass.getMethod("length")
        //使用传统方法,使用 Method 对象的 invoke ()方法
        println(mtd.invoke("111"))
        //使用调用运算符
        println(mtd("111"))
    }
    

    广义赋值运算符

    运算符 对应的方法
    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)

    这种广义的赋值运算符有些特殊,比如 a+=b,实际上相当于 a=a+b,因此在程序中进行 a+= b运算时,往往并不需要 a有 plusAssign()方法。对于广义赋值操作,例如 a+= b, 编译器会先判断 plusAssign()方法是否存在,如果存在, 则按如下步骤执行:

    1. 如果 plus()方法也存在, Kotlin将会报告错误(调用的目标方法不确定)。
    2. 确保 plusAssign()没有返回值,否则报告错误。
    3. 如果能通过前两步的检查,则转换为执行 a.plusAssign(b)。

    如果 plusAssign()方法不存在,那么 a+=b 将转换为 a=a+b 代码。

    相等和不等运算符

    运算符 对应的方法
    a==b a?.equals(b) ?: (b === null)
    a!=b !(a?.equals(b) ?: (b=== null)))

    Kotlin 的“==”不再比较两个变量是否引用同一个对象。实际上,“==” 与 equals()比较基本是等义的,只不过“==”比较是空指针安全的。
    Java 提供的“==”和“!=”在 Kotlin 中则由“===”和“!==”代替了。

    比较运算符

    运算符 对应的方法
    a>b a.compareTo(b)>0
    a<b a.compareTo(b)<0
    a>=b a.compareTo(b)>=0
    a<=b a.compareTo(b)<=0

    位运算符

    Kotlin 也提供了与 Java 功能完全相同的位运算符,但这些位运算符都不是以特殊字符给出的,而是以 infix 函数的形式给出的,因此程序只能用函数名来执行这些位运算符。
    Kotlin支持的位运算符同样有如下 7个。

    • and(bits): 按位与。当两位同时为 1 时才返回 1。
    • or(bits): 按位或。只要有一位为 1,即可返回 1。
    • inv(bits):按位非。单目运算符,将操作数的每个位(包括符号位)全部取反 。
    • xor(bits): 按位异或。当两位相同时返回 0,不同时返回 1。
    • shl(bits: 左移运算符。
    • shr(bits): 右移运算符。
    • ushr(bits): 无符号右移运算符。

    Kotlin 的位运算符只能对 Int和 Long 两种数据类型起作用。

    fun main(args: Array<String>) {
        println(5 and 9) //将输出 1
        println(5 or 9) //将输出 13
        println((-5).inv()) //将输出 4
        println(5 xor 9) //将输出 12
    }
    

    区间运算符

    Kotlin 提供了两个区间运算符,即闭区间运算符和半开区间运算符,它们都可以非常方便地构建一种数据结构,这种数据结构可包含特定区间内的所有值。

    闭区间运算符

    闭区间运算符a..b用于定义一个从a~b (包括a、b边界值)的所有值的区间。 对于闭区间运算符而言, a 不能大于 b, 否则程序运行时将会报错。

    半开区间运算符

    半开区间运算符 a until b用于定义一个从 a~b (包括 a边界值,但不包含 b边界值)的所有值的区间。半开区间运算符与闭区间运算符类似,a也不能大于 b。
    如果 a until b 中边界 a与边界 b 的值相等,就会产生一个空区间,该区间不包含任何值。

    反向区间

    如果程序希望区间可以从大到小,则可使用 downTo运算符(其实是一个 infix函数),该运算符同样构建一个闭区间。对于a downTo b而言,此时要求 b不能大于a。

    区间步长

    前面我们见到的所有区间的默认步长都是 1,也就是区间内两个值之间的差值是1。而通 过 step运算符(其实是一个 infix 函数)可以显式指定区间的步长。例如如下程序:

    fun main(args: Array<String>) {
        //步长为2
       for (num in 7 downTo 1 step 2){
           println(num)
       }
    }
    

    运算符重载

    Kotlin的运算符都是靠特定名称的方法支撑的,因此只要重载这些名称的方法,我们就可以为任意类添加这些运算符 。
    重载运算符的方法需要用 operator修饰符进行标记。

    重载单目前缀运算符

    上面的表中己经给出了单目前缀运算符对应的方法名,因此只要为任意类定义名为unaryPlus()、 unaryMinus()、 not(),且以 operator修饰的方法,程序即可对该类的实例使用+、-、!单目前缀运算符 。例如:

    data class Data(val x: Int, val y: Int) {
        //为 Data 类定义一个 unaryMinus ()方法 。
        operator fun unaryMinus(): Data {
            return Data(-x, -y)
        }
    }
    
    //以扩展方法的形式为 Data 类定义 not ()方法
    operator fun Data.not(): Data {
        return Data(-x, -y)
    }
    
    fun main(args: Array<String>) {
        val d = Data(4,10)
        //都输出Data(x=-4, y=-10)
        println(-d)
        println(d.unaryMinus())
        println(!d)
        println(d.not())
    }
    

    重载自加和自减运算符

    上面的表中己经给出了自加和自减运算符对应的方法名,因此只要为任意类定义名为 inc()、dec(),且以 operator修饰的方法,程序即可对该类的实例使用++、--运算符。

    data class Data(val x: Int, val y: Int) {
        //为 Data 类定义一个 inc ()方法
        operator fun inc(): Data {
            return Data(x+2, y+2)
        }
    }
    
    //以扩展方法的形式为 Data 类定义 not ()方法
    operator fun Data.dec(): Data {
        return Data(x-2, y-2)
    }
    
    fun main(args: Array<String>) {
        var d = Data(4,10)
        //输出Data(x=4, y=10)
        println(d++)
        //输出Data(x=6, y=-12)
        println(d)
        var d1 = Data(9,20)
        //输出Data(x=7, y=18)
        println(--d1)
        //输出Data(x=7, y=18)
        println(d1)
    }
    

    重载双目算术运算符

    上面的表中己经给出了双目算术运算符对应的方法名 , 因此只要为任意类定义名为 plus()、 minus()、 times()、 div()、 rem()、 rangeTo(),且以 operator修饰的方法,程序即可对该类的实例 使用+、-、*、/、%、..这些运算符。例如:

    data class Point(val x: Int, val y: Int) {
        //为 Point 类定义一个 minus ()方法
        operator fun minus(target: Point): Double {
            return Math.hypot((this.x - target.x).toDouble(), (this.y - target.y).toDouble())
        }
    }
    
    ///以扩展方法的形式为 Point 类定义 times ()方法
    operator fun Point.times(target: Point): Int {
        return Math.abs(this.x - target.x) * Math.abs(this.y - target.y)
    }
    
    fun main(args: Array<String>) {
        var p1 = Point(4, 10)
        var p2 = Point(5, 15)
        var distance = p1 - p2
        println("p1 与 p2 的距离为:${distance}")
        var area = p1 * p2
        println("p1 与 p2 围成矩形的面积为: ${area}")
    }
    

    相关文章

      网友评论

          本文标题:运算符和表达式

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