【Kotlin疑惑】在Kotlin类中重载一个算术运算符,并把该运算符声明为扩展函数会发生什么?

在Kotlin类中重载一个算术运算符,并把该运算符声明为扩展函数会发生什么?

实例

在这里插入图片描述

此时调用’+'运算符

在这里插入图片描述

报错如下

在这里插入图片描述

对错误进行解读
由于接收者类型无法匹配导致无法从候选方法中找到可以应用的

对错误进行分析

分析三种不同方式重载的plus函数

第一种:以标准的扩展函数形式重载plus函数

在这里插入图片描述

把kotlin代码反编译成java代码

在这里插入图片描述

通过反编译后我们可以发现此时plus函数处于PointKt类中,这也符合了我们之前篇章中说到“扩展函数并不是类的一部分,而是声明在类之外的”,在java中它把这个函数声明在了有着相似类名的类中,并且是一个静态函数。作为拓展函数的plus有着两个参数,kotlin在调用’+'时在java中被编译成下图

在这里插入图片描述

第二种:以标准的成员函数形式重载plus函数

在这里插入图片描述

把kotlin代码反编译成java代码

在这里插入图片描述

反编译后我们可以发现作为成员函数的plus现在只有一个参数,而kotlin在调用’+'时在java中被编译成下图

在这里插入图片描述

第三种:成员函数形式与扩展函数形式混合使用

在这里插入图片描述

把kotlin代码反编译成java代码

在这里插入图片描述

总分析

前两种形式是没有问题的写法,让我们着眼第三种的用法。把第三种的java代码与前两种的java代码相结合我们可以找出它们之间的一些联系与区别

联系与区别

它和第二种中的plus函数一样是Point类中的成员函数,但却有着两个参数
它和第一种中的plus函数一样有着两个参数,但没有第一种中plus函数的static声明

第三种编译出来的函数就像是缝合了前两种函数的写法一般。前面我们给出了第一种和第二种在调用plus函数的样子,而我们也可以据此推断出第三种调用时的样子:point.plus(?,new Point(3,4))。此时我就在想既然错误提示我们接收者类型不能匹配上,那为什么编译器不能把本身作为参数传入函数中呢?我可以尝试自己写一个带有两个参数的并且是运算符重载的plus函数吗?

结果如下

在这里插入图片描述

在kotlin层面重载该算术运算符只能存在一个参数

我猜想在kotlin编译器中在调用算术运算符时,若是成员函数只会提供一个参数的写法,若是扩展函数则使用提供两个参数的写法。第三种写法的plus函数既是成员函数又需要两个参数,可能就是如此才导致第三种写法无法成功运行

从equals方法我们可以看出继承自Any类的实现始终优先于扩展函数,而我们这种情况虽然不是继承自Any类,但是否也有着优先级的区别呢?

以上仅为我自己的想法,若有不同见解可以讨论,若有错误也请指出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值