kotlin学习(6)运算符重载和其他约定

约定

  在Kotlin中,可以调用自己代码中定义的函数,来实现语言结构。这戏功能与特定的函数命名相关,例如,在你的类中定义了一个名为plus的特殊方法,那么按照约定,就可以在该类的实例上使用 + 运算符,因此,我们把这种技术称为“约定”。


 

重载运算符

/*
*这里给一个类添加了plus方法来重载 + 运算符
*/
data point(val X:Int,val Y:Int){
        //operator修饰符是声明这个方法是用来重载的
    operator fun plus(other:point): point {
        return point(this.X+other.X,this.Y+other.Y)
    }
}
//重载之后,point对象就可以直接使用+运算符来操作两个对象了
fun main(args: Array<String>) {
    val a= point(1,1)
    val b= point(2,3)
    println(a+b)
}

可重载的二元运算符

表达式 函数名
a * b times
a / b div
a % b mod
a + b plus
a - b minus

  如果重载 + 或 * 计算的两边类型不同的话,那么不支持交换性,需要额外定义一个函数。

 

可重载的一元运算符

表达式 函数名
+a unaryPlus
-a unaryMinus
!a not
++a,a++ inc
--a,a-- dec

可重载的比较运算符

   equals和compareTo


 集合与区间的约定

  通过下标来访问元素:“get“和”set“

//这里使用了扩展函数实现get约定
operator fun point.get(index : int): Int{
    return when(index){
          0 -> x
          1 -> y
          else ->
                throw IndexOutOfBoundsException("Invalid coordinate $ index")
    }
}

//重载set
operator fun point.set(index : int,value : Int): Int{
    return when(index){
          0 -> x = value  //根据对应的index来修改值
          1 -> y = value
          else ->
                throw IndexOutOfBoundsException("Invalid coordinate $ index")
    }
}

>>>val p=point(10,20)
>>>println(p[1])
20

 


 

  in的约定,相对应的函数叫做contains

//使用in来检查点是否在矩形区域内
data class Rectangle(val upperLeft:point, val lowerRight:point)

operator fun Rectangle.contains(p:point):Boolean{
    //until构建了一个开区间
    return p.x in upperLeft.x until lowerRight.x &&
              p.y in upperLeft.y until lowerRight.y
}

 


//rangeTo的约定  1..10
operator fun <T: Comparable<T>> T.rangeTo(that: T): ClosedRange<T>

//在for循环中使用iterator的约定,这让迭代字符串成为可能
operator fun CharSequence.iterator(): CharIterator

>>>for (c in "abc")

 


 

解构声明和组件函数

  解构声明允许展开单个复合值,并使用它来初始化多个单独的变量

>>>val p = point(10, 20)
>>>val (x,y) = p
>>>println(x)
10
>>>printlb(y)
20

  对于数据类,编译器为每个在主构造方法中声明的属性生成一个componentN函数,下面展示如何手动为非数据类声明这些功能:、

//结构声明,可以在调用函数后轻松的展开一个对象,使用它的值
class point(val x: Int, val y: Int){
    operator fun component1() = x
    operator fun component2() = y
}

  此外,还可以用解构声明来遍历map for((key, value) in map){ println("$key -> $value") } 


 委托属性(不全)

//使用委托来实现懒汉式初始化(不调用不赋值,调用时才初始化)
fun loadEmails():Int{
    println("Load emails")
    return 1
}

class Person(val name:String){
    val emails by lazy{ loadEmails() }
}

>>>println(Person().emails)
Load emails
1

 

    

posted @ 2018-08-02 09:55  陆卯伍  阅读(268)  评论(0编辑  收藏  举报