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

立山  论坛元老 | 2024-10-27 07:18:46 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1028|帖子 1028|积分 3084

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
运算符重载

Java中的运算符根本只能应用于根本范例的+-*/,并不能对类对象举行这一系列的运算符操作,而Kotlin则赋予了我们使类对象也具有这种运算符操作,并且具体操作我们可以自定义。
假设我们存在一个类:Balance代表用户的余额,我们需要在其内部新增一个方法,并利用operator关键词举行修饰
   留意,函数名是有要求的,具体的操作符需要的函数名是不同等的,具体操作符与函数名的映射请到场下文。
  1. class Balance(val value: Int) {
  2.     operator fun plus(m : Balance) = Balance(this.value + m.value)
  3. }
复制代码
在这段代码中我们新增了plus函数,它会在Balance对象调用+操作时,现实调用的是Balance内部这个plus方法,实例如下:
  1. fun main() {
  2.     val a = Balance(5)
  3.     val b = Balance(1)
  4.     val c = a + b
  5.     println(c.value)
  6. }
复制代码
输出结果: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)aa.get(b)a = ca.set(b, c)a in bb.contains(a) 拓展函数与运算符重载的实践

当我们学习完拓展函数与运算符重载后,我们来举个实践例子,在开发的过程中我们有大概会让字符串的内容重复几遍,好比我想让abc这三个字符在一个字符串中重复n此,你大概会想到写个工具类再写一个for循环,但是学习完拓展函数与运算符重载之后,我们就可以来由Kotlin提供给我们的这两个语法糖来试试:
  1. operator fun String.times(n : Int): String {
  2.     val res = StringBuffer()
  3.     repeat(n) {
  4.         res.append(this)
  5.     }
  6.     return res.toString()
  7. }
复制代码
此中我们利用operator来告诉Kotlin此函数为运算符重载,然后利用String.times将这个函数做为String的拓展函数,在方法体内我们又利用repeat来使res重复添加n次。
然后我们就可以利用:“abc” * 3,的操作来使字符串重复三遍
  1. fun main() {
  2.     println("abc" * 3)
  3. }
  4. // 输出结果:abcabcabc
复制代码
高阶函数

从本节开始,我们将告别底子知识,转向Kotlin高级用法。
高阶函数的定义

高阶函数与Lambda是密不可分的,在Lambda中我们其时利用maxBy函数去求最长的字符串时讲到,maxBy是需要传入一个Lambda参数的,如果你想实现类似这种的,就需要用到高阶函数,那么高阶函数是什么呢?如果一个函数接收另一个函数作为参数,或者返回值的范例是 另一个函数,那么该函数就称为高阶函数。
在Java中我们不能将一个函数做为别的一个函数的参数,而Kotlin却增长了函数范例的概念,如果我们将这种函数范例添加到一个函数的参数声明或者返回值声明当 中,那么这就是一个高阶函数了。
高阶函数语法规则:
  1. (String, Int) -> Unit
复制代码
函数括号内是该函数需要接收什么参数,以及它的返回值是什么,这里的Unit相当于Java中的void关键字,将上述声明添加到方法中,那么此方法就称为高阶函数。
  1. fun times(func : (String, Int) -> Unit
  2. ) {    func("hello", 123)}
复制代码
高阶函数答应让函数范例的参数来决定函数的执行逻辑。即使是同一个高阶函数,只要传入差别的函数范例参数,那么它的执行逻辑和终极的返回结果就大概是完全差别的
高阶函数实践

知道了高阶函数能够做什么之后,我们来尝试自定义一个我们本身的高阶函数。
定义函数num1AndNum2,参数1为数字1,参数2为数字2,参数3为对应的高阶函数操作,我们在这个方法内返回了这个函数参数的调用,这意味着这个函数的结果是由我们传递的函数参数所决定的。
  1. fun num1AndNum2(n1 : Int, n2 : Int, oper : (Int, Int) -> Int) : Int {
  2.     return oper(n1, n2)
  3. }
复制代码
然后在HigherOrderFunction.kt文件中添加以下内容,此中plus主要返回n1和n2的相加结果,minus返回n1-n2的结果:
  1. fun plus(n1 : Int, n2 : Int): Int {
  2.     return n1 + n2
  3. }
  4. fun minus(n1 : Int, n2 : Int): Int {
  5.     return n1 - n2
  6. }
复制代码
接着,我们将参数和具体的函数参数传递给num1AndNum2这个函数
  1. fun main() {
  2.     println(num1AndNum2(1, 2, ::plus))
  3. }
复制代码
输出结果:3
但是你会想,这样也太麻烦了吧,我为什么不直接去调用HigherOrderFunction.kt,但是函数参数不但可以利用函数引用的方式(上文提到的方式),还可以利用Lambda、匿名函数、成员引用等,好比我们可以不用在HigherOrderFunction.kt中定义函数,而是在调用num1AndNum2时,利用Lambda效果也是一样的:
  1. println(num1AndNum2(1, 2) { n1, n2 -> n1 + n2 })
复制代码
高阶函数与apply

利用高阶函数还可以实现apply提供一个对象上下文的功能,新增如下方法:
  1. fun StringBuffer.build(block: StringBuffer.() -> Unit): StringBuffer {
  2.     block()
  3.     return this
  4. }
复制代码
可以看到我们这里利用到了拓展函数,但是奇怪的点是函数参数并不是我们之条件到的高阶函数定义的标准格式,现实环境是,我们如今利用的才是高阶函数的标准形式,在函数参数括号前利用ClassName.来告诉Kotlin,我的这个高阶函数是定义在哪个Class里面的。
  1. fun main() {
  2.     val list = listOf("a", "b", "c")
  3.     val res = StringBuffer().build {
  4.         append("开始完成任务... \n")
  5.         for (s in list) {
  6.             append("正在完成: $s \n")
  7.         }
  8.     }
  9.     println(res)
  10. }
复制代码
然后我们就可以不用在利用apply来提供一个对象的上下文了。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立山

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表