Kotlin基础语法-05-运算符重载-中缀表达式

Kotlin基础语法-05-运算符重载-中缀表达式

接上篇文章本文主要从kotlin 中的运算符重载、中缀表达式、反引号与typealies、 对象比较与值比较、DSL的基本概念、

1.运算符重载

来看一段代码

fun main( args : Array<String>){
    
    /// 这里的step 就是步进、中缀表达式。 
    for( i in 1..1000 setp 20 ){
    
        print("$i")
    }
    
}

编译后就会in就会被编译成一个Int迭代器, 稍有基础就能看懂、 不再赘述、

override fun iterator(): IntIterator = IntProgressionIterator(ifrst, last, step)

internal class IntProgressionIteraotr(first: Int, last: Int, val step : Int):IntIterator{
    
    private var next = first
    
    private val finalElement = last
    
    private var hasNext :Boolean if (step>0) first <=last else first > = last
    
    override fun hasNext(): Boolean = hasNext
    
    override fun nextInt():Int{
        
        val value  = next
        
        if(value == finalElement){
            
            hasNext = false
        }else{
            
            next += setp
        }
        return value 
    }
    
}

kotlin 中的运算符重载使用的是operator 关键字实现、修饰fun 时候后、 表示重载了函数名指代的运算符、
在结构的时候 ,我们标记过:

operator : 将一个函数标记为重载一个操作符或者实现一个约定。

再来一段代码

for( i  in 1.rangeTo 20  ){
    
    println("$i")
}

运算符的重载只能是在kotlin中定义好的、不能凭空来造。运算符是有上限的、
现在一共有120几个吧、

/// 看到了吧、这就是运算符重载的方法、
public operator fun rangeTo(other: Int) : IntRange

//  当然还有String + 号 也是重载 
public opterator fun  plus(other:Any?):String


2.中缀表达式

当然如果重载运算符不够用、这时候就需要使用中缀表达式
来个例子,


fun main(args: Array<String>) {

    println(5 vs 6)

    println(5.7 vs 2.3)

}

/**
 * 密闭类的三个值、
 */
sealed class CompareResult {

    object MORE : CompareResult() {

        override fun toString(): String {

            return "more"
        }
    }

    object LESS : CompareResult() {
        override fun toString(): String {
            return "less"
        }
    }

    object EQUAL : CompareResult() {
        override fun toString(): String {
            return "equal"
        }
    }

}


/**
 * Int 是该函数的接受者类型、也就是说只能是该类型可以调用该方法
 */
infix fun Int.vs(num: Int): CompareResult {
    if (this - num < 0) {
        return  CompareResult.LESS
    } else if (this - num > 0) {
        return   CompareResult.MORE
    } else {
        return    CompareResult.EQUAL
    }
}

infix  fun Float.vs(num:Float):CompareResult=
        if(this-num<0){
            CompareResult.LESS
        }else if(this- num>0){
            CompareResult.MORE
        }else{
            CompareResult.EQUAL
        }


infix  fun Double.vs(num:Double):CompareResult=
        if(this-num<0){
            CompareResult.LESS
        }else if(this - num >0){
            CompareResult.MORE
        }else{
            CompareResult.EQUAL
        }

打印结果:

less
more

Process finished with exit code 0

一个函数只有用于两个角色类似的对象时才将其声明为中缀函数。

推荐: and 、 to 、 zip

反例: add

最重要的一点:

如果一个方法会改动其接受者,那么不要声明为中缀表达式。

3. kotlin 的反引号``与typealies 和对象比较与值比较

/// 
fun  `123456`():Unit{
    println("test1")
}

123456一群数字肯定是没有意义的, 在java中也不能够作为一个方法名称,但是在kotlin中添加了``引号,则可以作为一个方法名使用,而且可以正常的调用。

注意: 这种写法只用于kotlin中,而且不推荐使用。因为调用起来很操心, 不省心。

例如``中间是一个空格,两个空格也是一个方法,这时候可能因为编程习惯多打了一个空格而造成调用方法的不同, 同时这么写也不能够让java代码调用。


public typealias A = File

fun main(args: Array<String>){
    /////  这么声明是合法的, 
    var a : File = A("/kotlinlearn/dev/xxx.json")
}

有一种类似于C/C++ 中的define 、宏定义的感觉。
再找一下koltin中类似映射的,例如:

@SinceKotlin("1.1") public typealias Error = java.lang.Error
@SinceKotlin("1.1") public typealias Exception = java.lang.Exception
@SinceKotlin("1.1") public typealias RuntimeException = java.lang.RuntimeException
@SinceKotlin("1.1") public typealias IllegalArgumentException = java.lang.IllegalArgumentException
@SinceKotlin("1.1") public typealias IllegalStateException = java.lang.IllegalStateException
@SinceKotlin("1.1") public typealias IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException
@SinceKotlin("1.1") public typealias UnsupportedOperationException = java.lang.UnsupportedOperationException

@SinceKotlin("1.1") public typealias NumberFormatException = java.lang.NumberFormatException
@SinceKotlin("1.1") public typealias NullPointerException = java.lang.NullPointerException
@SinceKotlin("1.1") public typealias ClassCastException = java.lang.ClassCastException
@SinceKotlin("1.1") public typealias AssertionError = java.lang.AssertionError

@SinceKotlin("1.1") public typealias NoSuchElementException = java.util.NoSuchElementException


@SinceKotlin("1.1") public typealias Comparator<T> = java.util.Comparator<T>

这里有一部分kotlin 中的类,映射的java中的类, 这样就形成了隔离层,既保留了java中的特性,又方便了kotlin 中的维护。

4. kotlin中如何比较对象

我们知道在java中A==B代表的意思是对象A与对象B是否相同,比较的是堆内存地址是否相同。
而例如String 的equals 代表的意思是对象A与对象B的值是否相同。

其实记住这句话就行了, 但是在kotlin中A == B代表的是对象A与B的值是否相同,而A===B则表示对象A与对象B是否是相同的对象

5. 外部DSL与内部DSL

什么是DSL语言, 怎么还区分外部和内部?

很简单, DSL 就是(Domain Specific Language ) 领域专用语言。例如json , xml , css, makefile, anko,kolley, build.gradle 这些就是。
外部内部的区分就是, 不依赖其他语言而且能都独自定义的就是外部的, 反之就是内部的。

举个例子,
例如json 就是表达了数据传输格式。 xml 既表达数据格式,也可以表示配置, 重要的是不依赖外部语言。
而anko ,kolley 就严重依赖了kotlin 才能够使用的,

例如anko 就是基于kotlin开发的
能够类似于butterknife的一个框架。 而kolley 则是类似于volley的一个网络请求架构。

注意, 不管内部DSL还是外部DSL 其特点是专有的,特殊领域内使用的,不要求复杂,包含所有,只要求精而专一。

6. 总结

多上手敲、多尝试、多思考、 有问题评论区我们共同讨论进步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章