广告
返回顶部
首页 > 资讯 > 精选 >Kotlin操作符重载的方法
  • 815
分享到

Kotlin操作符重载的方法

2023-06-30 04:06:34 815人浏览 安东尼
摘要

这篇“Kotlin操作符重载的方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Kotlin操作符重载的方法”文章吧。算数运

这篇“Kotlin操作符重载的方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Kotlin操作符重载的方法”文章吧。

算数运算操作符重载

在kotlin中我定义一个类

data class Point(val x: Int, val y: Int)

然后实例化两个对象

val p1 = Point(3,5)val p2 = Point(5,7)

想表示p1的元素x加上p2的元素x,p1的元素y,加上p2的元素y.然后输出一个p3.

val p3 = Point(p1.x + p2.x, p2.y + p2.y)

以上这种写法没有任何问题。不过我们可以利用Kotlin扩展函数简化上面的操作,我们给Point增加一个plus,并附加operator关键字。(增加operator的关键字是为了区分plus并不是一个普通的成员方法)

data class Point(val x: Int, val y: Int) {    operator fun plus(other: Point): Point {        return Point(x + other.x, y + other.y)    }}

接下来再来实现上面的需求.

val p3 = p1 + p2

这样表达起来更简洁了。 另外我们可以把plus作为Point的扩展方法

data class Point(val x: Int, val y: Int)operator fun Point.plus(other: Point): Point {    return Point(x + other.x, y + other.y)}

这种场景适用于Point存在于一个三方库,我们并能修改其中的内容. Kotlin中提供了以下操作符的重载. 只需要实现对应的方法即可。

Kotlin操作符重载的方法

之前我们定一个了plus,参数是Point,实际上对于个操作符重载并不局限于同一种类型,接下来我们来定一个times,允许你去扩展Ponit.

data class Point(val x: Int, val y: Int)operator fun Point.times(scale: Double): Point {    return Point((x * scale).toInt(), (y * scale).toInt())}fun main(args: Array<String>) {    val p = Point(10, 20)    println(p * 1.5)}

注意kotlin不支持交换性,例如我这里写成1.5 * p这里是不允许的。除非你去定一个

operator fun Double.times(p: Point): Point

返回类型同样也可以不是同一个类型,例如, 定义一个对char类型重载*操作符重复count后返回一个string.

operator fun Char.times(count: Int): String {    return toString().repeat(count)}fun main(args: Array<String>) {    println('a' * 3)}

复合运算操作符重载

我们在编程过程中通常会去把这种写法p = p + p1 写成 p += p1 这种简化写法,在kotlin中同样也支持这种+=操作符自定义操作。这种自定义运算操作符在什么场景下使用呢? 举个例子,我们定义集合

val numbers = ArrayList<Int>()numbers += 42println(numbers[0])

以上写法会感觉更加简洁。 我们在集合中定义操作符重载方法plusAssign(这里还有minusAssign, timesAssign等等)

operator fun <T> MutableCollection<T>.plusAssign(element: T) {    this.add(element)}

不过kotlin-stblib库已经帮你实现好了关于集合的类似操作. 在集合中+,-会累加集合原始后返回一个新的集合,如果使用+=,-=, 集合是mutable,会在本集合直接修改内容,如果集合是read-only,会返回一个拷贝后的修改集合。(这意味着如果集合是read-only,它的声明必须要是var, 不然它不能接受新返回拷贝后的修改集合). 你可以使用单独的元素或者集合(类型必须一致)进行复合运算符操作和算数运算符.

val list = arrayListOf(1, 2)list += 3                      val newList = list + listOf(4, 5) println(list)result : [1, 2, 3]println(newList)result : [1, 2, 3, 4, 5]

一元运算操作符重载

我们在编程过程中使用类似++a, a++, --a, a--同样支持运算符重载。仅仅需要重写下面的操作符函数即可

Kotlin操作符重载的方法

举个例子

operator fun BigDecimal.inc() = this + BigDecimal.ONEfun main(args: Array<String>) {    var bd = BigDecimal.ZERO    println(bd++)    println(++bd)}

这里注意到我只定一个inc(),同时也是支持bd++和++bd.

比较操作符重载

kotlin中还支持==, !=, >, <操作符重载. 对于==, !=我们重写equals方法. 这里还是拿Point来举栗子

data class Point(val x: Int, val y: Int)

我们这里声明成了data类,这个关键字加上了编译器会自动帮你实现equals方法,我们现在去掉,看看自己去写equals怎么写

class Point(val x: Int, val y: Int) {    override fun equals(obj: Any?): Boolean {        if (obj === this) return true      //1        if (obj !is Point) return false        return obj.x == x && obj.y == y    }}fun main(args: Array<String>) {    println(Point(10, 20) == Point(10, 20))    println(Point(10, 20) != Point(5, 5))  //2    println(null == Point(1, 2))}

这里我们需要关注一个//1 obj === this,这个===操作符是比较两个对象的引用是否一致,实际上和java中的==是一样的。 之前我们提到的操作符重载都会加上一个operator关键字,这里为什么是override?因为它重写了Any.class的equals方法.

Kotlin操作符重载的方法

这里看下//2!= 其实就是equals结果的取反. 除了=和!=之外这里还有>和<, 通过重写compareTo可以实现

class Person(        val firstName: String, val lastName: String) : Comparable<Person> {    override fun compareTo(other: Person): Int {        return compareValuesBy(this, other,            Person::lastName, Person::firstName)    }}fun main(args: Array<String>) {    val p1 = Person("Alice", "Smith")    val p2 = Person("Bob", "Johnson")    println(p1 < p2)}

这里的compareValuesBy顺便说说,它是kotlin-stblib提供的扩展函数

Kotlin操作符重载的方法

集合和区域的约定

在kotlin中我们可以使用类似于操作数组的方法操作集合,例如a[b]这种. 对于其它类,可以自定义操作符实现类似的操作

operator fun Point.get(index: Int): Int {    return when(index) {        0 -> x        1 -> y        else ->            throw IndexOutOfBoundsException("Invalid coordinate $index")    }}fun main(args: Array<String>) {    val p = Point(10, 20)    println(p[1])}

我们对于赋值操作同样也可以通过自定义operator

data class MutablePoint(var x: Int, var y: Int)operator fun MutablePoint.set(index: Int, value: Int) {    when(index) {        0 -> x = value        1 -> y = value        else ->            throw IndexOutOfBoundsException("Invalid coordinate $index")    }}fun main(args: Array<String>) {    val p = MutablePoint(10, 20)    p[1] = 42    println(p)}

另外一个知识点是自定义in操作符

Kotlin操作符重载的方法

in对于的contains函数,判断一个元素是否属于一个范围里.

data class Point(val x: Int, val y: Int)data class Rectangle(val upperLeft: Point, val lowerRight: Point)operator fun Rectangle.contains(p: Point): Boolean {    return p.x in upperLeft.x until lowerRight.x &&           p.y in upperLeft.y until lowerRight.y}fun main(args: Array<String>) {    val rect = Rectangle(Point(10, 20), Point(50, 50))    println(Point(20, 30) in rect)    println(Point(5, 5) in rect)}

迭代运算符重载

我们平时使用的

for (x in list) { ... }

将被转换为 list.iterator() 的调用,然后重复调用 hasNext 和 next 方法,就像在 Java 中一样。 请注意,在 Kotlin 中,它也是一种约定,这意味着可以将迭代器方法定义为扩展。这就解释了为什么可以迭代常规 Java 字符串:kotlin-stblib 在 Char-Sequence(String 的超类)上定义了一个扩展函数迭代器:

operator fun CharSequence.iterator(): CharIterator >>> for (c in "abc") {}

其它类型也可以通过自定义iterator实现自己类特定的操作。

import java.util.Dateimport java.time.LocalDateoperator fun ClosedRange<LocalDate>.iterator(): Iterator<LocalDate> =        object : Iterator<LocalDate> {            var current = start            override fun hasNext() =                current <= endInclusive            override fun next() = current.apply {                current = plusDays(1)            }        }fun main(args: Array<String>) {    val newYear = LocalDate.ofYearDay(2017, 1)    val daysOff = newYear.minusDays(1)..newYear    for (dayOff in daysOff) { println(dayOff) }}

解构声明

这个操作可以分解一个对象中成员,例如

>>> val p = Point(10, 20)>>> val (x, y) = p             >>> println(x)10>>> println(y)20

解构声明看起来有点像变量声明,不过它组合了多个变量值。实际上它在kotlin中也属于自定义操作符.去解构多个变量需要定义componentN,N是变量的位置.

Kotlin操作符重载的方法

class Point(val x: Int, val y: Int) {    operator fun component1() = x    operator fun component2() = y}

对于data类,解构已经帮你声明好了 另外解构声明还可以用在循环中

fun printEntries(map: Map<String, String>) {    for ((key, value) in map) {        println("$key -> $value")    }}fun main(args: Array<String>) {    val map = mapOf("oracle" to "Java", "JetBrains" to "Kotlin")    printEntries(map)}

Map中包含了扩展方法component1,component2返回key和value. 实际上你可以将上面的循环部分翻译

for (entry in map.entries) {    val key = entry.component1()    val value = entry.component2()    // ...}

以上就是关于“Kotlin操作符重载的方法”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: Kotlin操作符重载的方法

本文链接: https://www.lsjlt.com/news/327367.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Kotlin操作符重载的方法
    这篇“Kotlin操作符重载的方法”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Kotlin操作符重载的方法”文章吧。算数运...
    99+
    2023-06-30
  • Kotlin操作符重载实例详解
    目录算数运算操作符重载复合运算操作符重载一元运算操作符重载比较操作符重载集合和区域的约定迭代运算符重载解构声明总结算数运算操作符重载 在kotlin中我定义一个类 data clas...
    99+
    2022-11-13
  • 使用Kotlin怎么实现操作符与操作符重载
    这篇文章将为大家详细讲解有关使用Kotlin怎么实现操作符与操作符重载,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Kotlin基础教程之操作符与操作符重载Kotlin操作符的使用方法与其他...
    99+
    2023-05-31
    kotlin 操作符重载 操作符
  • Python3 操作符重载方法示例
    基础知识 实际上,“运算符重载”只是意味着在类方法中拦截内置的操作……当类的实例出现在内置操作中,Python自动调用你的方法,并且你的方法的返回值变成了相应操作的结果。以下是对重载的关键概念的复习: ...
    99+
    2022-06-04
    示例 操作 方法
  • Python中操作符重载用法分析
    本文实例讲述了Python中操作符重载用法。分享给大家供大家参考,具体如下: 类可以重载python的操作符 操作符重载使我们的对象与内置的一样。__X__的名字的方法是特殊的挂钩(hook),python...
    99+
    2022-06-04
    操作 Python
  • C#操作符重载的特点
    这篇文章主要讲解了“C#操作符重载的特点”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#操作符重载的特点”吧!C#操作符重载特点是什么呢?细心的朋友可能发现,C#虽然可以重载操作符,但和C...
    99+
    2023-06-17
  • Kotlin浅析null操作方法
    1.在java中由于null引起的空指针异常,是一个运行时异常。 在kotlin中为了避免这样的问题,会在编译期提示出来,而不是在运行期才报错。 1)比如我们把null赋值给一个已经...
    99+
    2022-11-13
  • C#运算符重载“>”的操作
    本篇内容主要讲解“C#运算符重载“>”的操作”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#运算符重载“>”的操作”吧!C#运算符重载“>”的操作问题的出现:今天一个同学在做...
    99+
    2023-06-18
  • C#操作符重载如何实现
    这篇文章主要讲解了“C#操作符重载如何实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#操作符重载如何实现”吧!C#操作符重载是什么?是指允许用户使用用户定义的类型编写表达式的能力。例如...
    99+
    2023-06-18
  • C++如何实现操作符重载
    这篇文章主要介绍了C++如何实现操作符重载,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。在C++中经常会遇到重载运算符的问题,其实运算符重载必须将运算符看做一个函数,分清他的...
    99+
    2023-06-04
  • C++操作符重载不同方式的区别是什么
    C++操作符重载不同方式的区别是什么 ,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。C++编程语言可以被看做是C语言的升级版本,它能够支持C语言中的所有功能,而...
    99+
    2023-06-17
  • C++中的操作符重载详细解析
    一、什么是操作符重载操作符重载可以分为两部分:“操作符”和“重载”。说到重载想必都不陌生了吧,这是一种编译时多态,重载实际上可以分为函数重载和操作符重载。运算符重载和函数重载的不同之...
    99+
    2022-11-15
    操作符重载 C++
  • C++超详细讲解操作符的重载
    目录一、需要解决的问题二、操作符重载三、小结一、需要解决的问题 下面的复数解决方案是否可行? 下面看一下复数的加法操作: #include <stdio.h> clas...
    99+
    2022-11-13
  • C#中怎么实现操作符重载
    C#中怎么实现操作符重载,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。C#操作符重载学习实践操作using System;  using&nb...
    99+
    2023-06-17
  • C#中怎么操作符重载应用
    今天就跟大家聊聊有关C#中怎么操作符重载应用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在C#中,操作符==是对象类的非虚的(操作符不可以为虚的)方法,它是按引用比较的。当你构建一...
    99+
    2023-06-17
  • c++运算符重载的方法是什么
    C++中的运算符重载方法是通过定义特殊的成员函数来实现的。重载运算符的函数被称为运算符函数,它们具有特殊的命名规则和语法。一般情况下...
    99+
    2023-09-14
    c++
  • C++超详细讲解数组操作符的重载
    目录一、字符串类的兼容性二、重载数组访问操作符三、小结一、字符串类的兼容性 问题:string 类对象还具备 C 方式字符串的灵活性吗?还能直接访问单个字符吗? string 类最大...
    99+
    2022-11-13
  • Python学习手册之内部方法、操作符重
     在上一篇文章中,我们介绍了 Python 的类和继承,现在我们介绍 Python 的内部方法、操作符重载和对象生命周期。  查看上一篇文章请点击:https://www.cnblogs.com/dustman/p/10016359.ht...
    99+
    2023-01-30
    手册 操作 方法
  • linux重启mysql的操作方法
    本文将为大家详细介绍“linux重启mysql的操作方法”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“linux重启mysql的操作方法”能够给你意想不到的收获,请大家跟着小编的思路慢慢深入,具体内容如下,一...
    99+
    2023-06-06
  • C++运算符重载方法怎么使用
    本篇内容介绍了“C++运算符重载方法怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!概念C++为了增强代码的可读性引入了运算符重载,运...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作