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

news/2024/11/20 10:24:43/

目录

扩展函数

语法结构

代码示例

运算符重载

语法结构

一元操作符

二元操作符

数值类型操作符

等于和不等于操作符

比较操作符

调用操作符


扩展函数

语法结构

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

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

代码示例

fun String.lettersCount(): Int {var count = 0for (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 + valuereturn Money(sum)}
}

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

一元操作符

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

二元操作符

操作符方法名
a + ba.plus(b)
a – ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.mod(b)
a..ba.rangeTo(b)
a in bb.contains(a)
a !in b!b.contains(a)
a += ba.plusAssign(b)
a -= ba.minusAssign(b)
a *= ba.timesAssign(b)
a /= ba.divAssign(b)
a %= ba.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] = ba.set(i, b)
a[i, j] = ba.set(i, j, b)
a[i_1, …, i_n] = ba.set(i_1, …, i_n, b)

等于和不等于操作符

操作符方法名
a == ba?.equals(b) ?: (b === null)
a != b!(a?.equals(b) ?: (b === null))

比较操作符

操作符方法名
a > ba.compareTo(b) > 0
a < ba.compareTo(b) < 0
a >= ba.compareTo(b) >= 0
a <= ba.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)


http://www.ppmy.cn/news/1260342.html

相关文章

占用站点资源,无法正常登录?这个功能帮助解决

在企业里随着PDM用户的增加PDM管理员是否发现原本的站点已经不够用出现部分用户占用站点资源导致其他用户无法正常登录导致该问题无法解决&#xff0c;本篇介绍PDM自动下线的功能助力企业解决问题&#xff0c;更好的帮助企业完成PDM的正常使用 今天我给大家带来的就是SOLIDWOR…

风力发电对讲 IP语音对讲终端IP安防一键呼叫对讲 医院对讲终端SV-6005网络音频终端

风力发电对讲 IP语音对讲终端IP安防一键呼叫对讲 医院对讲终端SV-6005网络音频终端 目 录 1、产品规格 2、接口使用 2.1、侧面接口功能 2.2、背面接口功能 2.3、面板接口功能 3、功能使用 1、产品规格 输入电源&#xff1a; 12V&#xff5e;24V的直流电源 网络接口&am…

Linux防火墙命令(关闭,启动,添加指定服务/端口)

不同版本的linux所用命令不相同: 查看linux版本命令: cat /etc/redhat-release [rootmyYUn software]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) 如果是centos7以上,用下面的命令第一行,如systemctl status firewalld.service 如果是centos6以下,用下面…

Hadoop学习笔记(HDP)-Part.07 安装MySQL

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

【Java面试——JUC全局观、原子类、锁、集合类、线程池、工具类】

目录 3.3 JUC全局观 JUC框架包含几个部分? Lock框架和Tools哪些核心的类? JUC并发集合哪些核心的类? JUC原子类哪些核心的类? JUC线程池哪些核心的类? 3.4 JUC原子类 线程安全的实现方法有哪些? 什么是CAS? CAS使用示例&#xff0c;结合AtomicInteger给出示例? CAS会有…

观海微电子---线路腐蚀的起因与对策

线路腐蚀的原理&#xff1a; 在线路表面的污染物中含有金属元素的离子或金属化合物&#xff0c; 在潮湿的空气中这些污染物与线路之间的冷凝水连成微电池&#xff0c;引发电化学反应&#xff0c;产品通电的情况下反应进行得更快&#xff0c;耗损线路导致线路腐蚀形成断线。 腐…

华为配置流量抑制示例

如拓扑图所示&#xff0c;SwitchA作为二层网络到三层路由器的衔接点&#xff0c;需要限制二层网络转发的广播、未知组播和未知单播报文&#xff0c;防止产生广播风暴&#xff0c;同时限制二三层网络转发的已知组播和已知单播报文&#xff0c;防止大流量冲击。 配置思路 用如下…

unity 2d 入门 飞翔小鸟 场景淡入淡出功能(三)

1、在图层新建个空的图层 场景2 2创建c#脚本 脚本创建好后&#xff0c;将脚本推拽进空白图层里面&#xff0c;将黑色图片拉进去脚本的参数里面&#xff0c;如上面最后一张图&#xff0c;两个切换的场景都要进行上述操作 using System.Collections; using System.Collection…