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. 總結

多上手敲、多嘗試、多思考、 有問題評論區我們共同討論進步。

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