Kotlin(十四) 扩展函数和运算符重载

目录

扩展函数

语法结构

代码示例

运算符重载

语法结构

一元操作符

二元操作符

数值类型操作符

等于和不等于操作符

比较操作符

调用操作符


扩展函数

语法结构

对于扩张函数的语法结构其实很简单,你想在那个类中添加扩张函数,那么你就用该类的类名加上点就可以,一般语法结构如下:

fun ClassName.methodName(): Int {
    return 0
}

代码示例

fun String.lettersCount(): Int {
    var count = 0
    for (letterChar in this) {
        if (letterChar.isLetter()) count++
    }
    return count
}

我们只需要创建一个为String.kt的文件,对于文件名我们可以随便命名,但是最好还是创建哪个类的扩展函数就以哪个类为文件名,这样便于查找,也方便后续的合作开发。

我们将lettersCount()方法定义成了String类的扩展函数,那么函数中就自动拥有了String实例的上下文。因此lettersCount()函数就不再需要接收一个字符串参数了,而是直接遍历this即可,因为现在this就代表着字符串本身。

定义好了扩展函数之后,统计某个字符串中的字母数量只需要这样写即可:

    val count = "dshdhakjdas2u121jksd23424h".lettersCount()
    println("含有$count 个字母")

除了String类之外,你还可以向任何类中添加扩展函数,Kotlin对此基本没有限制。

运算符重载

语法结构

class Obj{
    operator fun plus(obj: Obj) : Obj{
        //处理逻辑
    }
}

运算符重载使用的是operator关键字,只要在指定函数的前面加上operator关键字,就可以实现运算符重载的功能了。

在上述语法结构中,关键字operator和函数名plus都是固定不变的,而接收的参数和函数返回值可以根据你的逻辑自行设定。那么上述代码就表示一个Obj对象可以与另一个Obj对象相加,最终返回一个新的Obj对象。对应的调用方式如下:

val obj1 = Obj()
val obj2 = Obj()
val obj3 = obj1 + obj2

这种obj1 + obj2的语法看上去好像很神奇,但其实这就是Kotlin给我们提供的一种语法糖,它会在编译的时候被转换成obj1.plus(obj2)的调用方式。

了解了运算符重载的基本语法之后,下面我们开始实现一个更加有意义功能:让两个Money对象相加。

首先定义Money类的结构,这里我准备让Money的主构造函数接收一个value参数,用于表示钱的金额。创建Money.kt文件,然后定义plus运算符重载,代码如下所示:

class Money(val value: Int) {

    operator fun plus(money: Money): Money {
        val sum = money.value + value
        return Money(sum)
    }
}

可以看到,这里使用了operator关键字来修饰plus()函数,这是必不可少的。在plus()函数中,我们将当前Money对象的value和参数传入的Money对象的value相加,然后将得到的和传给一个新的Money对象并将该对象返回。这样两个Money对象就可以相加了,就是这么简单。除了plus()函数,Kotlin还提供了很多,如下:

一元操作符

操作符 方法名
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc()

二元操作符

操作符 方法名
a + b a.plus(b)
a – b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.mod(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.modAssign(b)

数值类型操作符

操作符 方法名
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 == b a?.equals(b) ?: (b === null)
a != b !(a?.equals(b) ?: (b === null))

比较操作符

操作符 方法名
a > b a.compareTo(b) > 0
a < b a.compareTo(b) < 0
a >= b a.compareTo(b) >= 0
a <= b a.compareTo(b) <= 0

调用操作符

操作符 方法名
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. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-07 12:08:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-07 12:08:04       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-07 12:08:04       82 阅读
  4. Python语言-面向对象

    2023-12-07 12:08:04       91 阅读

热门阅读

  1. activeMq

    activeMq

    2023-12-07 12:08:04      57 阅读
  2. C/C++---------------LeetCode第2154. 将找到的值乘以 2

    2023-12-07 12:08:04       62 阅读
  3. Scala--2

    2023-12-07 12:08:04       56 阅读
  4. 产品运营常用的ChatGPT通用提示词模板

    2023-12-07 12:08:04       74 阅读
  5. React 表单组件实现

    2023-12-07 12:08:04       59 阅读
  6. 五花八门客户问题(BUG) - 数据库索引损坏

    2023-12-07 12:08:04       71 阅读
  7. Metasploit的安全防御和逃逸

    2023-12-07 12:08:04       38 阅读
  8. SELinux refpolicy详解(9)

    2023-12-07 12:08:04       73 阅读
  9. Metasploit的漏洞挖掘和利用

    2023-12-07 12:08:04       38 阅读
  10. 详解ES6中的symbol

    2023-12-07 12:08:04       56 阅读
  11. Shopify 开源 WebAssembly 工具链 Ruvy

    2023-12-07 12:08:04       54 阅读