芬兰湾的科特林学习教程之操作符重载详解

  

  

在芬兰湾的科特林中,我们可以用约定的操作符,代替调用代码中以特定的命名定义的函数,来实现与之对应的操作,例如在类中定义了一个名为加上的特殊方法,就可以使用加法运算符+代替+()的方法调用。由于你无法修改已有的接口定义,因此一般可以通过扩展函数来为现有的类增添新的约定方法,从而使得操作符重载这一语法糖适应任何现有Java类的。

  


  

  

我们就从最简单直接的例子+这一类算术运算符开始。

        数据类点(val x: Int, val y: Int) {   操作符有趣+(其他:点)=(x +其他。x, y + other.y)   操作符有趣+(价值:Int)=" toString: ${点(x +值,y +价值)}”   }      有趣的主要(args: Array      
      <李>操作符修饰符是必须的,否则加上只是一个普通方法,不能通过+调用。   <李>操作符是有优先级的,比较*优先级高于+,不论这个操作符应用于什么对象,这种优先级都是固定存在的。   <李> +方法的参数类型是任意的,因此可以方法重载,但是参数数量只能是1,因为+是一个二元操作符的话语方法的返回值类型也是任意的。   <李>如果出现多个方法签名相同的运营商扩展方法,根据进口决定使用哪个一,例如:李   
     //第一个文件:   包package0   运营商有趣点。次(价值:Int)=点(x *值,y *值)//第二个文件:   包package1   运营商有趣点。次(价值:Int)=单位//什么都不做。//使用第一个扩展操作符:   进口package0.times   val newPoint=点(1、2)* 3      

芬兰湾的科特林为一些基本类型预定义了一些操作符方法,我们平时常写的基本数据计算也可以翻译成调用这些操作符方法,比如(2 + 3)* 4可以翻译成2. +(3)同学(4),2 + 3 * 4可以翻译成2. +(4)(3.倍)。根据扩展函数的语法,扩展函数无法覆盖与类已有的方法签名相同的方法,因此,不必担心随随便便给Int自定义一个+扩展方法就能让1 + 1变得不等于2 .

  

同时,所有操作符都针对基本类型做了优化,比如1 + 2 * 3、4 & lt;5,不会为它们引入函数调用的开销。

  

所有可重载的算术运算符有:

  

           表达式,   翻译为               a + b   a.plus (b)         a - b   a.minus (b)         a * b   a.times (b)         a/b   a.div (b)         % b   a.rem (b), a.mod (b),(在芬兰湾的科特林1.1中被弃用)         a . .   a.rangeTo (b)            

  

它们的优先级与普通的数字类型运算符优先级相同。其中rangeTo会在下面说明。

  

  

           表达式,   翻译为               +=b   a.plusAssign (b)         a - b=a.minusAssign (b)         *=b   a.timesAssign (b)         a/b=a.divAssign (b)         %=b   a.remAssign (b), <罢工> a.modAssign (b), (在芬兰湾的科特林1.1中被弃用)            

  

对于以上广义赋值操作符:

  
      <李>如果对应的二元算术运算符函数也可用,则报错的话语对应plusAssign.minus,时间等也类似。   <李>返回值类型必须为单位。   <李>如果执行+=b时plusAssign不存在,会尝试生成=a + b,其中a + b的使用的就是+操作符方法,相当于调用a=a.plus (b)。并且此时会要求a + b的+方法的返回值类型必须与一个类型一致(如果单独使用a + b不做此要求)。   
        数据类的大小(var宽度:Int=0, var高度:Int=0) {   操作符有趣+(其他:大小):{大小   返回大小(宽度+其他。宽度,高度+ other.height)   }   运营商有趣plusAssign(其他:大小){   宽度+=other.width   身高+=other.height   }   }      有趣的主要(args: Array      

我们使用这个例子来理解:为什么使用var定义的s1会导致+=报错呢?因为理论上,执行+=时,既可以调用s1=s1 + s2,也就是s1=s1.plus (s2),又可以调用s1.plusAssign (s2),都符合操作符重载约定,这样就会产生歧义,而如果使用val定义s1,则只可能执行s1.plusAssign (s2),因为s1不可被重新赋值,因此s1=s1 + s2这样的语法是出错的,永远不能能调用,那么调用s1 +=s2就不会产生歧义了。

芬兰湾的科特林学习教程之操作符重载详解