【编程语言】Kotlin快速入门 - 高阶函数与运算符重载

news2024/10/24 2:08:17

运算符重载

Java中的运算符基本只能应用于基本类型的+-*/,并不能对类对象进行这一系列的运算符操作,而Kotlin则赋予了我们使类对象也具有这种运算符操作,并且具体操作我们可以自定义。

假设我们存在一个类:Balance代表用户的余额,我们需要在其内部新增一个方法,并使用operator关键词进行修饰

注意,函数名是有要求的,具体的操作符需要的函数名是不一致的,具体操作符与函数名的映射请参加下文。

class Balance(val value: Int) {
    operator fun plus(m : Balance) = Balance(this.value + m.value)
}

在这段代码中我们新增了plus函数,它会在Balance对象调用+操作时,实际调用的是Balance内部这个plus方法,实例如下:

fun main() {
    val a = Balance(5)
    val b = Balance(1)
    val c = a + b
    println(c.value)
}

输出结果:6

运算符表达式和实际调用函数对照表
运算符实际调用函数
a+ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.rem(b)
a++a.inc()
a–a.dec()
+aa.unaryPlus()
-aa.unaryMinus()
!aa.not()
a == ba.equals(b)
a > ba.equals(b)
a < ba.equals(b)
a >= ba.equals(b)
a <= ba.compareTo(b)
a…ba.rangeTo(b)
a[b]a.get(b)
a[b] = ca.set(b, c)
a in bb.contains(a)
拓展函数与运算符重载的实践

当我们学习完拓展函数与运算符重载后,我们来举个实践例子,在开发的过程中我们有可能会让字符串的内容重复几遍,比如我想让abc这三个字符在一个字符串中重复n此,你可能会想到写个工具类再写一个for循环,但是学习完拓展函数与运算符重载之后,我们就可以理由Kotlin提供给我们的这两个语法糖来试试:

operator fun String.times(n : Int): String {
    val res = StringBuffer()
    repeat(n) {
        res.append(this)
    }
    return res.toString()
}

其中我们使用operator来告诉Kotlin此函数为运算符重载,然后使用String.times将这个函数做为String的拓展函数,在方法体内我们又使用repeat来使res重复添加n次。

然后我们就可以使用:“abc” * 3,的操作来使字符串重复三遍

fun main() {
    println("abc" * 3)
}
// 输出结果:abcabcabc

高阶函数

从本节开始,我们将告别基础知识,转向Kotlin高级用法。

高阶函数的定义

高阶函数与Lambda是密不可分的,在Lambda中我们当时使用maxBy函数去求最长的字符串时讲到,maxBy是需要传入一个Lambda参数的,如果你想实现类似这种的,就需要用到高阶函数,那么高阶函数是什么呢?如果一个函数接收另一个函数作为参数,或者返回值的类型是 另一个函数,那么该函数就称为高阶函数。

在Java中我们不能将一个函数做为另外一个函数的参数,而Kotlin却增加了函数类型的概念,如果我们将这种函数类型添加到一个函数的参数声明或者返回值声明当 中,那么这就是一个高阶函数了。

高阶函数语法规则:

(String, Int) -> Unit

函数括号内是该函数需要接收什么参数,以及它的返回值是什么,这里的Unit相当于Java中的void关键字,将上述声明添加到方法中,那么此方法就称为高阶函数。

fun times(func : (String, Int) -> Unit) {
    func("hello", 123)
}

高阶函数允许让函数类型的参数来决定函数的执行逻辑。即使是同一个高阶函数,只要传入不同的函数类型参数,那么它的执行逻辑和最终的返回结果就可能是完全不同的

高阶函数实践

知道了高阶函数能够做什么之后,我们来尝试自定义一个我们自己的高阶函数。

定义函数num1AndNum2,参数1为数字1,参数2为数字2,参数3为对应的高阶函数操作,我们在这个方法内返回了这个函数参数的调用,这意味着这个函数的结果是由我们传递的函数参数所决定的。

fun num1AndNum2(n1 : Int, n2 : Int, oper : (Int, Int) -> Int) : Int {
    return oper(n1, n2)
}

然后在HigherOrderFunction.kt文件中添加以下内容,其中plus主要返回n1和n2的相加结果,minus返回n1-n2的结果:

fun plus(n1 : Int, n2 : Int): Int {
    return n1 + n2
}

fun minus(n1 : Int, n2 : Int): Int {
    return n1 - n2
}

接着,我们将参数和具体的函数参数传递给num1AndNum2这个函数

fun main() {
    println(num1AndNum2(1, 2, ::plus))
}

输出结果:3

但是你会想,这样也太麻烦了吧,我为什么不直接去调用HigherOrderFunction.kt,但是函数参数不仅可以使用函数引用的方式(上文提到的方式),还可以使用Lambda、匿名函数、成员引用等,比如我们可以不用在HigherOrderFunction.kt中定义函数,而是在调用num1AndNum2时,使用Lambda效果也是一样的:

println(num1AndNum2(1, 2) { n1, n2 -> n1 + n2 })
高阶函数与apply

使用高阶函数还可以实现apply提供一个对象上下文的功能,新增如下方法:

fun StringBuffer.build(block: StringBuffer.() -> Unit): StringBuffer {
    block()
    return this
}

可以看到我们这里使用到了拓展函数,但是奇怪的点是函数参数并不是我们之前提到的高阶函数定义的标准格式,实际情况是,我们现在使用的才是高阶函数的标准形式,在函数参数括号前使用ClassName.来告诉Kotlin,我的这个高阶函数是定义在哪个Class里面的。

fun main() {
    val list = listOf("a", "b", "c")
    val res = StringBuffer().build {
        append("开始完成任务... \n")
        for (s in list) {
            append("正在完成: $s \n")
        }
    }
    println(res)
}

然后我们就可以不用在使用apply来提供一个对象的上下文了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2222032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微积分复习笔记 Calculus Volume 1 - 3.4 Derivatives as Rates of Change

3.4 Derivatives as Rates of Change - Calculus Volume 1 | OpenStax

京东 北京 java 中级: 哪些情况下的对象会被垃圾回收机制处理掉? 哪些对象可以被看做是 GC Roots 呢?对象不可达,一定会被垃圾收集器回收么?

我同学最近在面试java的岗位, 这是他遇到的某些关于java的JVM中垃圾回收相关的部分的问题, 他来问我, 我特以此文章来解答. 公司 京东 base 北京 面试时间 2024年10月23日16:00:00 他跟我说, 面试官一上来就问了一个关于JVM的问题, 直接就给他难住了, 问题是 : 哪些情况下…

数据结构《顺序表》

文章目录 前言一、什么是顺序表&#xff1f;1.1 顺序表的概念1.2 顺序表的建立 二、MyArrayList的实现三、顺序表的方法四、关于顺序表的例子总结 前言 提示&#xff1a;这里涉及到的ArrayList类是一个泛型类&#xff0c;同时后面的很多内容都会涉及到泛型&#xff0c;如果不了…

【蓝队技能】【内网隧道工具流量分析】FRPNPSreGeorgVenom

蓝队技能 FRP&NPS&reGeorg&Venom 蓝队技能总结前言一、FRP1.1 流量分析1.2 特征提取 二 NPS1.1 流量分析1.2 特征提取 三、reGeor1.1 特征提取 四、Venom1.1 特征提取 总结 前言 本文聚焦内网隧道代理技术&#xff0c;涵盖Frp、Nps、Neo-reGeorg及Venom等工具。这些…

潜水定位通信系统的功能和使用方法_鼎跃安全

潜水定位通信系统是保障潜水安全与作业高效的关键设备。它利用先进的声呐、无线电等技术&#xff0c;可精准定位潜水员位置。在水下能实现潜水员之间以及与水面的双向通信&#xff0c;确保信息及时传递。具备高可靠性和稳定性&#xff0c;即使在复杂水环境中也能正常运行。 一、…

Git Push(TODO)

最近经常碰到GIT push不上去的问题。到处求人解决也真是尴尬&#xff0c;想自己看看&#xff0c;所以刚刚在github上建了一个仓&#xff0c;试了下。结果如下&#xff1a; 暂时可能还不行&#xff0c;因为数据都是加密的&#xff0c;没法看到具体GIT的交互信息。。。 后面再想办…

算法的学习笔记—两个链表的第一个公共结点(牛客JZ52)

&#x1f600;前言 在链表问题中&#xff0c;寻找两个链表的第一个公共结点是一个经典问题。这个问题的本质是在两个单链表中找到它们的相交点&#xff0c;或者说它们开始共享相同节点的地方。本文将详细讲解这个问题的解题思路&#xff0c;并提供一种高效的解决方法。 &#x…

WPFDeveloper正式版发布

WPFDeveloper WPFDeveloper一个基于WPF自定义高级控件的WPF开发人员UI库&#xff0c;它提供了众多的自定义控件。 该项目的创建者和主要维护者是现役微软MVP 闫驚鏵: https://github.com/yanjinhuagood 该项目还有众多的维护者&#xff0c;详情可以访问github上的README&…

Golang | Leetcode Golang题解之第497题非重叠矩形中的随机点

题目&#xff1a; 题解&#xff1a; type Solution struct {rects [][]intsum []int }func Constructor(rects [][]int) Solution {sum : make([]int, len(rects)1)for i, r : range rects {a, b, x, y : r[0], r[1], r[2], r[3]sum[i1] sum[i] (x-a1)*(y-b1)}return Sol…

SpringBoot项目ES6.8升级ES7.4.0

SpringBoot项目ES6.8.15 升级到 ES7.4.0 前言 由于公司内部资产统一整理&#xff0c;并且公司内部部署有多个版本的es集群&#xff0c;所以有必要将目前负责项目的ES集群升级到公司同一版本7.4.0。es6到es7的升级变化还是挺大的&#xff0c;因此在这里做一下简单记录&#xf…

从新手到高手:map和set的使用技巧全攻略(C++)

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C&#xff1a;由浅入深篇 小新的主页&#xff1a;编程版小新-CSDN博客 前言&#xff1a; 本章节讲解的map和set底层…

C++新基础类型(C++11~C++20)

本文章记录C11~C20的新基础类型。 1.整数类型long long long long类型是C11引入的。在C标准中规定&#xff0c;long long是一个至少为64位的整数类型。可以使用LL和ULL字面量后缀进行初始化。格式化打印时分别用%lld和%llu。 long long x 12345LL; unsigned long long y 4…

简单的windows java -jar 无法启动jar包解决方法

简单的windows java -jar 无法启动jar包解决方法 1. 问题 我们项目是使用nacos作为注册中心以及配置中心&#xff0c;我们本地使用idea 进行服务配置以及启动发现没有问题&#xff0c;然后我们的服务经过maven install 打包后发布到LINUX服务启动也没有问题&#xff0c;但是我…

Artistic Oil Paint 艺术油画着色器插件

只需轻轻一点&#xff0c;即可将您的视频游戏转化为艺术品&#xff01;&#xff08;也许更多…&#xff09;。 ✓ 整个商店中最可配置的选项。 ✓ 六种先进算法。 ✓ 细节增强算法。 ✓ 完整的源代码&#xff08;脚本和着色器&#xff09;。 ✓ 包含在“艺术包”中。 &#x1f…

上拉电阻和下拉电阻在电路中的作用(一)

上拉电阻和下拉电阻在电路中的作用&#xff08;一&#xff09; 1.什么是上下拉电阻2.上下拉电阻的作用&#xff1a;2.1.维持输入引脚处于稳定状态。2.2.配合三极管和MOS进行电平转换电路设计2.3.OC、OD电路&#xff08;Open Collector集电极开路、Open Drain漏电极开路&#xf…

优化UVM环境(九)-将interface文件放在env pkg外面

书接上回&#xff1a; 优化UVM环境&#xff08;八&#xff09;-整理project_common_pkg文件 My_env_pkg.sv里不能包含interface&#xff0c;需要将my_intf.sv文件放在pkg之外

Leetcode 1135. 最低成本连通所有城市

1.题目基本信息 1.1.题目描述 想象一下你是个城市基建规划者&#xff0c;地图上有 n 座城市&#xff0c;它们按以 1 到 n 的次序编号。 给你整数 n 和一个数组 conections&#xff0c;其中 connections[i] [x_i, y_i, cost_i] 表示将城市 x_i 和城市 y_i 连接所要的cost_i&…

【scene_manager】与 MoveIt 机器人的规划场景进行交互

scene_manager Scene Manager包是由 Robotnik 创建的 ROS 包&#xff0c;旨在帮助构建和与 MoveIt 机器人的规划场景进行交互。 背景信息 MoveIt 规划场景 是一个用于存储机器人周围世界的表示&#xff08;外部碰撞&#xff09;以及机器人自身状态&#xff08;内部碰撞和当…

LeetCode.102 二叉树的层序遍历

题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 提示&#xff1a; 树中节点数目在范围 [0, 2000] 内-1000 < Node.val < 1000 解题思路 对二叉树进行层序遍历即可&am…

最好的ppt模板网站是哪个?做PPT不可错过的18个网站!

现在有很多PPT模板网站&#xff0c;但真正免费且高质量的不多&#xff0c;今天我就分享主流的国内外PPT模板下载网站&#xff0c;并且会详细分析这些网站的优缺点&#xff0c;这些网站都是基于个人实际使用经验的&#xff0c;免费站点会特别标注&#xff0c;让你可以放心下载&a…