美文网首页Kotlin学习之路
Kotlin进阶语法之操作符重载与中缀调用

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

作者: wanderingGuy | 来源:发表于2019-05-26 14:41 被阅读0次

操作符

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

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

我们更熟悉二元操作符,比如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}")
    println("一元加法运算 value = ${(+number1).value}")
    println("二元加法运算 value = ${(number1 + number2).value}")

    val number3 = Number(876543210)
    println("索引 number3 = ${number3[6]}")
}

//输出
Number value = -3
一元加法运算 value = 3
二元加法运算 value = 3
索引 number3 = 6

中缀调用

上面的例子都比较好理解,操作符也是我们常见的,试想一下Kotlin是否支持自定义的操作符呢?回答是肯定的,它是Kotlin语言的一大特性。

来看一个栗子:

//定义String1类
class String1(var str: String)
//声明中缀调用符"love"
infix fun String1.love(other: String1): String {
//    return this.str + "love" + other.str//理想情况
    return if(other.str == "you") "gun" else "meizizi" //实际情况
}

使用infix关键字声明中缀函数,中缀符为'love',根据传入参数判断返回值,只要不是'you',都是美滋滋。如果是'you',心拔凉拔凉的。另需注意中缀函数也是扩展函数的一种,需在顶层包内声明。

来测试一下看看效果。

@JvmStatic
fun main(args: Array<String>) {
    val I = String1("i")
    val YOU = String1("you")
    //两个String1类型之间支持中缀符'love'
    print(I love YOU)
}
//输出 gun

相关文章

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

    操作符 首先要清楚常见的操作符有哪些? 对一元操作符来说包括'!'、'++'、'--',我们常用的是非操作和自增操...

  • Kotlin流程控制语句笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin泛型笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin与Java互操作笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin协程笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin空指针安全(null-safety)笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin函数式编程笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin面向对象编程笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin类型系统笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

  • Kotlin委托(Delegation)笔记

    Kotlin语言基础笔记 Kotlin流程控制语句笔记 Kotlin操作符重载与中缀表示法笔记 Kotlin扩展函...

网友评论

    本文标题:Kotlin进阶语法之操作符重载与中缀调用

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