专栏名称: wanderingguy
职业码农,退役运动员 简书: https://www.jianshu.com/u/0bcca8b23127
目录
相关文章推荐
格上财富  ·  为什么普通人必须要投资 ·  昨天  
拾榴询财  ·  春节旅行归来,一些有意思的见闻 ·  3 天前  
格上财富  ·  伟大投资者的十大特质 ·  4 天前  
格上财富  ·  中国船舶工业是如何发展起来的? ·  5 天前  
51好读  ›  专栏  ›  wanderingguy

Kotlin进阶语法之操作符重载与中缀调用

wanderingguy  · 掘金  ·  · 2019-08-20 00:13

正文

阅读 12

Kotlin进阶语法之操作符重载与中缀调用

操作符

首先要清楚常见的操作符有哪些?

对一元操作符来说包括'!'、'++'、'--',我们常用的是非操作和自增操作。

我们更熟悉二元操作符,比如 a + b 在这个场景下'+'就是二元操作符,常见的二元操作符就是加减乘除等算术符号。

在Kotlin中还增加了其他二元操作符,比如:in/!in(范围操作符)。

另外还有一些其他的操作符,比如索引访问操作符a[i]、调用操作符a()。

操作符重载

你是否想过类似 println("s" + 1) 这样的代码为何会编译通过,一个String类型和一个Int类型是如何相加的?为什么String类型可以像数组一样可以通过下标访问字符 sss[1]

没错,无论'+' 还是取索引都是一种操作符,Kotlin支持操作符的重载,也就是可以将不同类型的对象进行算术运算或其它运算。

我们看看Kotling中String的源码。

public class String : Comparable<String>, CharSequence {
    companion object {}
    
    //+操作符重载
    public operator fun plus(other: Any?): String

    //索引访问操作符重载
    public override fun get(index: Int): Char
    ...
}
复制代码

操作符重载方法需声明 operator 关键字,plus方法对应'+'操作符,参数声明为Any?,可见正式因为String重载了'+'操作符,且参数为Any?,所以在代码中可以用一个String类型的对象"+" 任意一个对象。

接下来看一下操作符对应的重载方法名。

一元操作符 对应方法
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++/++a a.inc()
a--/--a a.dec()
二元操作符 对应方法
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.compareTo(b) > 0

回到上面的例子,如果我们稍微调整一下代码 println(1+"s") 这样就会编译报错,可以想见Int类并不支持plus且参数为String的重载。 我们看一下Int类关于plus的重载函数。

# Int
/** Adds the other value to this value. */
public operator fun plus(other: Byte): Int
/** Adds the other value to this value. */
public operator fun plus(other: Short): Int
/** Adds the other value to this value. */
public operator fun plus(other: Int): Int
/** Adds the other value to this value. */
public operator fun plus(other: Long): Long
/** Adds the other value to this value. */
public operator fun plus(other: Float): Float
/** Adds the other value to this value. */
public operator fun plus(other: Double): Double
复制代码

通过重载函数的声明可以确认Int类型只能与一个数字相 '+'。

接下来我们举几个例子加深理解。

class Number constructor(var value: Int)

// 重载一元操作符+,使其对Number中实际数据取绝对值
operator fun Number.unaryPlus(): Number {
    this.value = Math.abs(value)
    return this
}

// 非运算取相反数 
operator fun Number.not(): Number {
    this.value = -value
    return this
}

// 重载Number类的加法运算符 但并不做真正的加法
operator fun Number.plus(value: Int): Number {
    return Number(this.value)
}

// 重载Number类的加法运算符 支持Number类型
operator fun Number.plus(value: Number): Number {
    return Number(this.value)
}

// 重载Number类的索引运算 返回某个位上的数字
operator fun Number.get(index: Int): Int {
    return this.value / Math.pow(10.toDouble(), index.toDouble()).toInt() % 10
}
复制代码

测试函数

@JvmStatic
fun main(args: Array<String>) {

    val number1 = Number(-3)
    val number2 = Number(2)
    println("Number value = ${number1.value}






请到「今天看啥」查看全文