Android Kotlin 基本語法2

不知道如何測試下列語法可以參考如何使用Android Studio 測試資料?

  1. 操作符重載
  2. 資料區間用法
  3. map使用方法
  4. 內部靜態變數
  5. 靜態變數
  6. 當資料如果是?型態宣告
  7. 資料使用!!,強制將Int?轉Int
  8. data class用法
  9. 強制轉型
  10. run、with、apply、also用法

  • 1. 操作符重載
  • 這裡只舉例,因為數量很多,其他請各位舉一反三囉,參考此處

    class ReloadOperator(var arg1: Double, var arg2: Double) {
        operator fun plus(value: Double): ReloadOperator {
            return ReloadOperator(arg1+value, arg2+value)
        }
    
        operator fun invoke(): Double {
            return arg1+arg2
        }
    }
    val test = ReloadOperator(10.0,30.0)
    val data = test + 10.0 //會執行plus
    //data()會執行invoke()
    println("data.arg2 = ${data.arg2} data() = ${data()}")
    //data = 40.0 data2 = 60.0
    

  • 2. 資料區間用法
  • for(index in 0 until 5) {
        println("index = $index")
        //0 1 2 3 4
    }
    for(index in 0..5) {
        println("index = $index")
        //0 1 2 3 4 5
    }
    for(index in 10 downTo 0 step 3) {
        println("index = $index")
        //10 7 4 1
    } 
    

  • 3. map使用方法
  • //可讀可寫 mutableMapOf
    //只可讀 mapOf
    //第一種:可讀可寫
    val map = mutableMapOf("a" to 20, "b" to "AAA", "c" to 10.0)
    map["a"] = 32
    println("map ${map["a"]}") //打印 map 32
    
    //第二種:可讀不可寫
    val map2 = mapOf("a" to 1, "b" to 2, "c" to 3)
    map2["a"] = 32 //錯誤導致無法編譯
    println("map ${map["a"]}") //打印 map 1
    
    //遍歷map
    for((key, value) in map2) {
        println("key = $key, value = $value")
    }
    

  • 4. 內部靜態變數,使用lib的方法也如下
  • class AAA {
        companion object {
            const val data1 = 1
            const val data2 = 2
            init {
                System.loadLibrary("native-lib")
            }
        }
    }
    class BBB {
        fun setData(data: Int) {
            AAA.data1 = 2
            if(AAA.data2 == 2) {
                println("data = ${AAA.data2}")
            }
        }
    }
    

  • 5. 靜態變數
  • object SDK {
        var init: Boolean? = false
    }
    class main {
        fun initData(flag: Boolean?) {
            if(SDK.init != null) {
                SDK.init = true
            }
        }
    }
    

  • 6. 如果資料是?型態宣告
  • fun isCount(data: Int?): Int {
        return data ?: return -1//如果data is null回傳-1
    }
    @Test
    fun test1() {
        println(isCount(0))//0
        println(isCount(null))//-1
    }
    

  • 7. !!使用方法
  • 舉例強制將Int?轉Int,注意使用!!,如果是null將會發生異常

    private var data: Int? = 1
    fun checkData(): Int {
        if(data != null) {
            return data!!
        }
        return -1
    }
    //多個val data就可以去掉!!囉
    private var data: Int? = 1
    fun checkData(): Int {
        val data = data
        if(data != null) {
            return data
        }
        return -1
    }
    

  • 8. data class用法
  • data class Book(var name: String, var price: Int) {
        fun plusPrice(value: Int) {
            //plus 是將price+value在返回值
            price = price.plus(value)
        }
        fun minusPrice(value: Int) {
            //minus 是將price-value在返回值
            price = price.minus(value)
        }
    }
    val book: Book? = Book("AABBCC", 59)
    println("price = ${book?.price}") //輸出59
    book?.plusPrice(10)
    println("price = ${book?.price}") //輸出69
    book?.minusPrice(20)
    println("price = ${book?.price}") //輸出49
    
    
    data class TestDataClass(
        var name: String = "Apple", 
        val value: Int = 0
    )
    class TestClass(
        val name: String = "Apple", 
        var value: Int = 0
    )
    
    @Test
    fun test1() {
        val testDataClass = TestDataClass().also {
            it.name = "Windows"
        }
        val testClass = TestClass().also {
            it.value = 1
        }
    
        //data class覆寫了toString
        println(testDataClass.toString())
        println(testClass.toString())
    
        //打印如下 
        //TestDataClass(name=Windows, value=0)
        //com.xxx.ExampleUnitTest$TestClass@2fd66ad3
    
        //多了快速取值的方法 
        val (name, value) = testDataClass
        println("name = $name, value = $value")
        //打印如下   
        // name = Windows, value = 0
        //克隆一份一模一樣資料的
    
        val testDataClass1 = testDataClass.copy()
        println(testDataClass)
        println(testDataClass1)
        //打印資料如下 
        //TestDataClass(name=Windows, value=0)
        //TestDataClass(name=Windows, value=0)
    }
    
    //test2 與 test3比較就可以明顯看出class與data class的不同了
    @Test
    fun test2() {
        val testDataClass = TestDataClass().also {
            it.name = "Windows"
        }
    
        val testDataClass1 = TestDataClass().also {
            it.name = "Windows"
        }
    
        //記憶體位置不同
        println(testDataClass === testDataClass1)
        //false
    
        //相同物件
        println(testDataClass == testDataClass1)
        //true
    
        println(testDataClass.hashCode())
        //-1050734083
    
        println(testDataClass1.hashCode())
        //-1050734083 明顯看到相同
    
        testDataClass1.name = "Apple"
        //變更testDataClass1 名稱
    
        println(testDataClass === testDataClass1)
        //false
    
        println(testDataClass == testDataClass1)
        //false
    
        println(testDataClass.hashCode())
        //-1050734083
    
        println(testDataClass1.hashCode())
        //1967772678
    
        println(testDataClass.toString())
        //TestDataClass(name=Windows, value=0)
    
        println(testDataClass1.toString())
        //TestDataClass(name=Apple, value=0)
    
    }
    @Test
    fun test3() {
        val testClass = TestClass().also {
            it.name = "Windows"
        }
        val testClass1 = TestClass().also {
            it.name = "Windows"
        }
    
        //記憶體位置不同
        println(testClass === testClass1)
        //false
    
        //相同物件
        println(testClass == testClass1)
        //false
    
        println(testClass.hashCode())
        //1375995437
    
        println(testClass1.hashCode())
        //1338841523 明顯看到不同
    
        testClass1.name = "Apple"
        //變更testClass1 名稱
    
        println(testClass === testClass1)
        //false
    
        println(testClass == testClass1)
        //false
    
        println(testClass.hashCode())
        //1375995437
    
        println(testClass1.hashCode())
        //1338841523
    }
    
    //此處有個重點在Kotlin與Java上的差異
    1.Referential Equality 參考性 與記憶體有關
    2.Structural Equality 結構性 Object相等
    
    Java
    Referential Equality ==
    Structural Equality equals
    
    Kotlin
    Referential Equality ===
    Structural Equality == , equals
    

  • 9. 強制轉型
  • fun main() {
        var data1: String = "1234"
        var data2: Int = 20
        onDataChange(data1)
        onDataChange(data2)
    }
    
    fun onDataChange(data: Any) {
        val data1: String? = data as? String
        val data2: Int? = data as? Int
        if(data1 != null) {
            //有資料
            println("{data1 ${data1}}")
        }
        if(data2 != null) {
            //有資料
            println("{data2 ${data2}}")
        }
    }
    

  • 10. run、with、apply、also用法
  • run+let,run回傳最後一行給let,let再回傳最後一行,給result做為結果

    data class Book(var name: String, var price: Int) {
        fun plusPrice(value: Int) {
            //plus 是將price+value在返回值
            price = price.plus(value)
        }
        fun minusPrice(value: Int) {
            //minus 是將price-value在返回值
            price = price.minus(value)
        }
    }
    
    
    
    //第一種 
    val book: Book? = Book("apple", 10)
    val result = book?.run {
        //run內部時,是this
        println("this $this ------- name $name")
        true
    }.let {//run 和 with都是回傳最後一行
        //此時的it是true
        println("let $it")
        it != null
    }
    println("result $result")
    //打印
    //this Book(name=apple, price=10) ------- name apple
    //let true
    //result true
    
    
    
    //第二種
    val book: Book? = null
    val result = book?.run {
        //run內部時,是this
        println("this $this ------- name $name")
        true
    }.let {//run 和 with都是回傳最後一行
        //此時的it是true
        println("let $it")
        it != null
    }
    println("result $result")
    //此處run不會進入,因為run不會處理null,如果要確保let不是null改用with
    //打印let null
    //result false
    

    當with是null時,最後回傳的依然是最後一行
    因為with的內部可以有?

    //第一種
    val book: Book? = null
    val result = with(book as Book?) {
        println("this $this")
        true
    }.let {
        //因為with可以在那處理null
        //不會因為null直接到let
        //所以基本上就是with的最後一行資料進來
        it != null
    }
    println("result $result")
    //打印
    //this null
    //result true
    
    
    
    //第二種
    val book: Book? = Book("Apple", 10)
    val result = with(book as Book?) {
        println("this $this")
        true
    }.let {
        //因為with可以在那處理null
        //不會因為null直接到let
        //所以基本上就是with的最後一行資料進來
        it != null
    }
    println("result $result")
    //打印
    //this Book(name=Apple, price=10)
    //result true
    

    apply 可以整理完資料將自己返回

    val list = ArrayList().apply {
        add("1234")
        add("3456")
    }.let { listTemp ->//it可以像這樣改名字
        //整理好的資料是it
        println("let it $listTemp, size ${listTemp.size}")
        //此時輸出size = 2
    
        listTemp
    }
    println("list -> $list, size -> ${list.size}")
    //let it [1234, 3456], size 2
    //list -> [1234, 3456], size -> 2
    

    also 與apply一樣的意思
    只是變成it, it可以像上面listTemp一樣改名字

    val list = ArrayList().also {
        //it是剛建立好的ArrayList
        it.add("1234")
        it.add("3456")
        println("this $it size ${it.size}")
    }
    println("list $list, size ${list.size}")
    //this [1234, 3456] size 2
    //list [1234, 3456], size 2
    


    上面皆是版本ext.kotlin_version = “1.5.0″測試的


    更多相關可以參考這裡


    相關文章

    Android Kotlin 基本語法1Android Kotlin 基本語法3
    1. var 可變變數
    2. val 不可變更參數
    3. Array 用法
    4. ArrayList 用法
    5. List的filter、sort、map、forEach
    6. when 用法
    7. fun 函式用法
    8. if 表達式
    9. for 表達式
    10. 擴充函數(自定義函式)
    1. class多建構式
    2. 內部class用法
    3. interface
    4. enum class 用法
    5. sealed class 用法
    6. open 用法
    Android Kotlin 基本語法4Android Kotlin Classes and Objects-1
    1. 為基礎類型新增函式
    2. Abstract技巧使用
    3. throw使用方法
    4. 利用let特性處理資料型態?
    5. 快速初始化Array
    6. 快速將兩個資料交換
    7. 自定義待處理的fun
    8. 幫loop設定標籤
    1. 多個class與執行順序
    2. init與constructor執行優先序
    3. open繼承與禁止繼承
    4. 不同的寫法,影響override能不能改變值
    5. 繼承與當前Class執行順序
    6. 由inner class去找parent的super
    7. 繼承多個class時,選擇指定的Parent
    8. private protected public internal修飾符差異
    Android Kotlin Classes and Objects-2Android Kotlin 委託屬性
    1. 幫List新增swap功能
    2. 擴充外加函式,幫助程式簡化
    3. T,多類型引入
    4. T搭配in、out使用
    5. 1個對象的object用法
    6. 類型別名
    7. 內聯類
    8. 委託
    1. 變數委託
    2. lazy懶加載用法+String.split
    3. 可觀察屬性observable
    4. 委託內建map
    5. 本地委託屬性,此方法可以減少加載
    6. 委託屬性,唯獨與可讀可寫的方法
    7. 將舊方法棄用

    訂閱Codeilin的旅程,若有最新消息會通知。

    廣告

    發表迴響

    在下方填入你的資料或按右方圖示以社群網站登入:

    WordPress.com 標誌

    您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

    Facebook照片

    您的留言將使用 Facebook 帳號。 登出 /  變更 )

    連結到 %s

    透過 WordPress.com 建置的網站.

    向上 ↑

    %d 位部落客按了讚: