Android Kotlin 委託屬性

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

  1. 變數委託
  2. lazy懶加載用法+String.split
  3. 可觀察屬性observable
  4. 委託內建map
  5. 本地委託屬性,此方法可以減少加載
  6. 委託屬性,唯獨與可讀可寫的方法
  7. 將舊方法棄用

  • 1. 變數委託
  • class Example {
        var p: String by Delegate()
    }
    class Delegate {
        //重寫get
        operator fun getValue(
            thisRef: Any?,
            property: KProperty
        ): String {
            return "$thisRef, thank you for delegating " +
                    "${property.name} to me!"
        }
        //重寫set
        operator fun setValue(
            thisRef: Any?,
            property: KProperty,
            value: String
        ) {
            println("$value has been assigned to " +
                    "${property.name} in $thisRef.")
        }
    }
    @Test
    fun test() {
        val e = Example()
        //打印com.xxxx.ExampleUnitTest$Example@157632c9,
        //thank you for delegating 'p' to me!
        println(e.p)
    
        //打印123 has been assigned to 'p' in
        //com.xxxx.ExampleUnitTest$Example@157632c9.
        e.p = "123"
    }
    

  • 2. lazy懶加載用法+String.split
  • private val data: String by lazy {
        println("init data")
        "init data"
    }
    @Test
    fun test() {
        //呼叫這行時,打印 init data
        val array = data.split(" ")
    
        //呼叫這行時打印 array = [init, data], array.size 2
        println("array = $array, array.size ${array.size}")
    }
    

  • 3. 可觀察屬性observable
  • //可觀察屬性observable
    class User {
        //初始值是
        var dataName: String by Delegates
            .observable("") {
                prop, old, new ->
            println("${prop.name} $old -> $new")
        }
    }
    @Test
    fun test() {
        val user = User()
        user.dataName = "first"
        //打印dataName  -> first
        
        user.dataName = "second"
        //打印dataName first -> second
    }
    

  • 4. 委託內建map
  • //唯讀的map
    class User(
        map: Map
    ) {
        val name: String by map
        val age: Int     by map
    }
    //可讀可寫
    class MutableUser(
        map: MutableMap
    ) {
        var name: String by map
        var age: Int     by map
    }
    private val user = User(
        mapOf(
            "name" to "John Doe",
            "age"  to 25
        )
    )
    private val mutableUser = MutableUser(
        mutableMapOf(
            "name" to "John Doe",
            "age"  to 25
        )
    )
    @Test
    fun test() {
        println(user.name) 
        // 打印 John Doe
        
        println(user.age)  
        // 打印 25
        println(mutableUser.name) 
        // 打印 John Doe
        
        println(mutableUser.age)  
        // 打印 25
    }
    

  • 5. 本地委託屬性,此方法可以減少加載
  • interface I {
        fun doSomething()
        fun isValid(): Boolean
    }
    private fun example(
        someCondition: Boolean, 
        computeFoo: () -> I
    ) {
        //當someCondition == true,才會加載computeFoo
        val memoizedFoo by lazy(computeFoo)
        if (someCondition && memoizedFoo.isValid()) {
            memoizedFoo.doSomething()
        }
    }
    private val callback = object : I {
        override fun doSomething() {
            println("doSomething")
        }
        override fun isValid(): Boolean {
            return false
        }
    }
    @Test
    fun test() {
        example(true) {
            println("process data")
            callback
        }
    }
    

  • 6. 委託屬性,唯讀與可讀可寫的方法
  • fun resourceDelegate(): ReadWriteProperty =
        object : ReadWriteProperty {
            var curValue = 0
            override fun getValue(
                thisRef: Any?, 
                property: KProperty
            ): Int = curValue
            override fun setValue(
                thisRef: Any?, 
                property: KProperty, 
                value: Int
            ) {
                curValue = value
            }
        }
    val readOnly: Int by resourceDelegate()  
    // ReadWriteProperty as val
    var readWrite: Int by resourceDelegate()
    @Test
    fun test() {
        readOnly = 0//錯誤
        readWrite = 0//正常
    }
    

    7. 將舊方法棄用

    class MyClass {
        //將舊的參數棄用方式
        var newName: Int = 0
        @Deprecated("Use 'newName' instead", 
            ReplaceWith("newName")
        )
        var oldName: Int by this::newName
    }
    @Test
    fun test() {
        val myClass = MyClass()
        // Notification: 'oldName: Int' is deprecated.
        // Use 'newName' instead
        myClass.oldName = 42
        println(myClass.newName) // 42
    }
    


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


    更多相關可以參考這裡


    相關文章

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

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

    廣告

    Android Kotlin Classes and Objects-2

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

    1. 幫List新增swap功能
    2. 擴充外加函式,幫助程式簡化
    3. T,多類型引入
    4. T搭配in、out使用
    5. 1個對象的object用法
    6. 類型別名
    7. 內聯類
    8. 委託

  • 1. 幫List新增swap功能
  • 快速兩資料交換參考Android Kotlin 基本語法3

    fun MutableList.swap(index1: Int, index2: Int) {
        val tmp = this[index1] 
        this[index1] = this[index2]
        this[index2] = tmp
    }
    fun MutableList.swap2(index1: Int, index2: Int) {
        //用Android Kotlin 基本語法3那篇的,快速兩資料交換的方法
        this[index1] = this[index2].also {
            this[index2] = this[index1]
        }
    }
    @Test
    fun test() {
        val list = mutableListOf(10, 20, 30)
        list.swap(0, 2) 
        list.forEach {
            println("A = $it")
        }
        /*
        打印
        A = 30
        A = 20
        A = 10*/
        list.swap2(0, 2)
        list.forEach {
            println("B = $it")
        }
        /*
        打印
        B = 10
        B = 20
        B = 30*/
    }
    

  • 2. 擴充外加函式,幫助程式簡化
  • class Host(val hostname: String) {
        fun printHostname() { print(hostname) }
    }
    
    class Connection(val host: Host, val port: Int) {
        fun printPort() { 
            print(port) 
        }
        //利用此方法幫助程式簡化
        fun Host.printConnectionString() {
            printHostname()
            print(":")
            printPort()
        }
    
        fun connect() {
            host.printConnectionString()
        }
    }
    
    @Test
    fun test() {
        Connection(Host("kotl.in"), 443).connect()
    }
    

  • 3. T,多類型引入
  • class Box(t: T) {
        var value = t
    }
    
    @Test
    fun test() {
        val box = Box("123")
    }
    

  • 4. T搭配in、out使用
  • //T搭配out用法
    interface Source {
        //in -> 引入T, out -> return T, 此處為"return T"
        fun nextT(): T
    }
    fun demo(callback: Source) {
        val objects: Source = callback 
        println(objects.nextT())//打印"hello"
    }
    val sourceCallback = object : Source{
        override fun nextT(): String {
            return "hello"
        }
    }
    @Test
    fun test() {
        demo(sourceCallback)
    }
    //T搭配in用法
    interface Comparable {
        //in -> 引入T, out -> return T, 此處為"引入T"
        fun compareTo(data1: T, data2: T): Boolean
    }
    fun demo(x: Comparable) {
        //打印false
        println(x.compareTo(1.0, 2.0)) 
        // Double是Number的子類型
    
        //因此可以這樣賦予
        val y: Comparable = x // OK!
    }
    @Test
    fun test2() {
        demo(object : Comparable{
            override fun compareTo(
                data1: Number, 
                data2: Number
            ): Boolean = data1 == data2
        })
    }
    

  • 5. 1個對象的object用法
  • class C {
        // 私有函數內,返回的函數也是私有的
        private fun foo() = object {
            val x: String = "x"
        }
    
        // 公有函數,內容也是公有
        fun publicFoo() = object {
            val x: String = "x"
        }
    
        fun bar() {
            val x1 = foo().x        
            // private fun 正常
    
            val x2 = publicFoo().x  
            // fun 錯誤
        }
    }
    

  • 6. 類型別名
  • //typealias 是重新將底層類型命名
    //testString is String
    typealias testString = String
    class ExampleUnitTest {
    
        @Test
        fun test() {
            val data: testString = "1234"
            println(data)
            //print 1234
        }
    
    }
    

    7. 內聯類,為了減少大量程式碼的開銷

    //inline在1.5版以後,不推薦使用的內聯類
    //應改為下方
    @JvmInline
    value class Password(val value: String)
    
    @Test
    fun test() {
        //securePassword運行的時候,內部會簡化成只代表String
        val securePassword = 
            Password("Don't try this in production")
        println(securePassword)
    }
    
    var counter = 0
        set(value) {
            if (value >= 0)
                field = value
            //field 就是backing fields
        }
    
    //還有支持一些基本用法
    //但有一些限制,不能含有 backing fields
    //只能做簡單的計算(沒有lateinit/delegated屬性)
    @JvmInline
    value class Name(val s: String) {
        init {
            require(s.length > 0) {
                //require <= 0
                //throw java.lang.IllegalArgumentException
            }
        }
        val length: Int
            get() = s.length
        fun greet() {
            println("Hello, $s")
        }
    }
    @Test
    fun test() {
        val name = Name("Kotlin")
        name.greet() 
        // `greet` 方法會作為一個靜態方法調用
    
        println(name.length) 
        //屬性的get方法會作為一個靜態方法調用
    }
    
    //內聯類允許繼承
    interface Printable {
        fun prettyPrint(): String
    }
    
    @JvmInline
    value class Name(val s: String) : Printable {
        override fun prettyPrint(): String = "Let's $s!"
    }
    
    @Test
    fun test() {
        val name = Name("Kotlin")
        println(name.prettyPrint()) 
        // Still called as a static method
    }
    //typealias 是重新將底層類型命名
    //@JvmInline
    //    value是生成新的類型
    typealias NameTypeAlias = String
    
    @JvmInline
    value class NameInlineClass(val s: String)
    
    fun acceptString(s: String) {}
    fun acceptNameTypeAlias(n: NameTypeAlias) {}
    fun acceptNameInlineClass(p: NameInlineClass) {}
    
    @Test
    fun test() {
        val nameAlias: NameTypeAlias = ""
        val nameInlineClass: NameInlineClass = 
            NameInlineClass("")
    
        val string: String = ""
    
        acceptString(nameAlias) 
        //正常,因為typealias 是重新將底層類型命名
    
        acceptString(nameInlineClass) 
        //錯誤,內聯是新建新的類型,所以不等於String
        
    
        // And vice versa:
        acceptNameTypeAlias(string) 
        //正常,因為typealias 是重新將底層類型命名
    
        acceptNameInlineClass(string) 
        //錯誤,內聯是新建新的類型,所以不等於String
    }
    

    8. 委託(Delegation)

    interface Base {
        val message: String
        fun print()
    }
    class BaseImpl(x: Int) : Base {
        override val message = "BaseImpl: x = $x"
        override fun print() { println(message) }
    }
    class Derived(b: Base) : Base by b {
        //by b -> 如果此處有override,以此處為優先
        //若沒有override,則使用Base內預設的.
        override val message = "Message of Derived"
    }
    @Test
    fun test() {
        val b = BaseImpl(10)
        val derived = Derived(b)
        derived.print()
        println(derived.message)
        /*
        BaseImpl: x = 10
        Message of Derived
         */
    }
    


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


    更多相關可以參考這裡


    相關文章

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

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

    廣告

    Android Kotlin Classes and Objects-1

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

    1. 多個class與執行順序
    2. init與constructor執行優先序
    3. open繼承與禁止繼承
    4. 不同的寫法,影響override能不能改變值
    5. 繼承與當前Class執行順序
    6. 由inner class去找parent的super
    7. 繼承多個class時,選擇指定的Parent
    8. private protected public internal修飾符差異

  • 1. 多個class與執行順序
  • class InitOrderDemo(name: String) {
        val firstProperty = "First p: $name"
                                .also(::println)
    
        init {
            println("First init test ${name}")
        }
    
        val secondProperty = "Second p: ${name.length}"
                                 .also(::println)
    
        init {
            println("Second init test ${name.length}")
        }
    }
    
    @Test
    fun test() {
        InitOrderDemo("123")
        /*
        First p: 123
        First init test 123
        Second p: 3
        Second init test 3
         */
    }
    

  • 2. init與constructor執行優先序
  • class Constructors {
        init {
            println("Init block")
        }
    
        constructor(i: Int) {
            println("Constructor $i")
        }
    }
    
    @Test
    fun test() {
        Constructors(12)
        //init比constructor早執行,就算init放下面也是如此
        //Init block
        //Constructor 12
    }
    

  • 3. open繼承與禁止繼承
  • open class Shape {
        open fun draw() {
            println("Shape draw")
        }
        fun fill() { /*...*/ }
    }
    
    //因為Circle沒有open,所以不能繼承
    class Circle() : Shape() {
        override fun draw() {
            super.draw()
            println("Circle draw")
        }
    }
    
    open class Rectangle() : Shape() {
        final override fun draw() {
            super.draw()
            println("Rectangle draw")
        }
    }
    
    open class Test2() : Rectangle() {
        //因為Rectangle的draw是final所以禁止override
    }
    

  • 4. 不同的寫法,影響override能不能改變值
  • interface Shape {
        val vertexCount: Int
    }
    
    class Rectangle(
        override val vertexCount: Int = 4
    ) : Shape 
    // Always has 4 vertices
    
    class Polygon : Shape {
        override val vertexCount: Int = 0  
    }
    
    @Test
    fun test() {
        Rectangle(5)
        Polygon()//不能改變vertexCount值
    }
    

  • 5. 繼承與當前Class執行順序
  • open class Base(val name: String) {
    
        init { 
            println("Init a base class") 
        }
    
        open val size: Int = name.length.also { 
            println("Init size: $it") 
        }
    }
    
    class Derived(
        name: String,
        val lastName: String,
    ) : Base(
        name.replaceFirstChar { 
            it.uppercase() 
        }.also { 
            println("Argument for the base class: $it") 
        }
    ) {
        init { 
            println("Init a derived class") 
        }
    
        override val size: Int = 
            (super.size + lastName.length)
                .also { 
            println("Init size: $it") 
        }
    }
    
    @Test
    fun test() {
        Derived("apple", "windows")
        /*
        Argument for the base class: Apple
        Init a base class
        Init size: 5
        Init a derived class
        Init size: 12
         */
    }
    

  • 6. 由inner class去找parent的super
  • open class Rectangle {
        open fun draw() { 
            println("Drawing a rectangle") 
        }
        val borderColor: String get() = "black"
    }
    
    class FilledRectangle: Rectangle() {
        override fun draw() {
            val filler = Filler()
            filler.drawAndFill()
        }
    
        inner class Filler {
            fun fill() { 
                println("Filling") 
            }
            fun drawAndFill() {
                super@FilledRectangle.draw() 
    
                fill()
                println("color " +
                        super@FilledRectangle.borderColor
                        )
     
            }
        }
    }
    
    @Test
    fun test() {
        FilledRectangle().draw()
        /*
        Drawing a rectangle
        Filling
        color black
         */
    }
    

    7. 繼承多個class時,選擇指定的Parent

    open class Rectangle {
        open fun draw() { 
            println("Rectangle draw") 
        }
    }
    
    interface Polygon {
        fun draw() { 
            println("Polygon draw") 
        } // interface members are 'open' by default
    }
    
    class Square() : Rectangle(), Polygon {
        // The compiler requires draw() to be overridden:
        override fun draw() {
            super.draw() // call to Rectangle.draw()
            super.draw() // call to Polygon.draw()
        }
    }
    
    @Test
    fun test() {
        Square().draw()
        /*
        Rectangle draw
        Polygon draw
         */
    }
    

    8. Private protected public internal修飾符差異

    //private:只能在內部看到
    //protected:在內部看得到,繼承後也看得到
    //internal:只能在相同模塊看到
    //public: 任何客戶端都可以見到
    open class Outer {
        private val a = 1
        protected open val b = 2
        internal val c = 3
        val d = 4  // 都沒設定預設 public
    
        protected class Nested {
            public val e: Int = 5
        }
    }
    
    class Subclass : Outer() {
        // a 不可見
        // b、c、d 可見
        // Nested 和 e 可見
    
        override val b = 5   // 繼承父,所以一樣是protected
    }
    
    class Unrelated(val o: Outer) {
        // o.a、o.b 不可見
        // o.c 和 o.d 可見(相同模塊)
        // Outer.Nested 不可見,Nested::e 也不可見
    }
    
    internal open class Example {
    
        class Test1: Example() {//相同模塊所以可以繼承
    
        }
        inner class Test2: Example() {//相同模塊所以可以繼承
    
        }
    }
    
    class Test3: Example() {//不同模塊所以不能繼承
    
    }
    


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


    更多相關可以參考這裡


    相關文章

    Android Kotlin 基本語法1Android Kotlin 基本語法2
    1. var 可變變數
    2. val 不可變更參數
    3. Array 用法
    4. ArrayList 用法
    5. List的filter、sort、map、forEach
    6. when 用法
    7. fun 函式用法
    8. if 表達式
    9. for 表達式
    10. 擴充函數(自定義函式)
    1. 操作符重載
    2. 資料區間用法
    3. map使用方法
    4. 內部靜態變數
    5. 靜態變數
    6. 當資料如果是?型態宣告
    7. 資料使用!!,強制將Int?轉Int
    8. data class用法
    9. 強制轉型
    10. run、with、apply、also用法
    Android Kotlin 基本語法3Android Kotlin 基本語法4
    1. class多建構式
    2. 內部class用法
    3. interface
    4. enum class 用法
    5. sealed class 用法
    6. open 用法
    1. 為基礎類型新增函式
    2. Abstract技巧使用
    3. throw使用方法
    4. 利用let特性處理資料型態?
    5. 快速初始化Array
    6. 快速將兩個資料交換
    7. 自定義待處理的fun
    8. 幫loop設定標籤
    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的旅程,若有最新消息會通知。

    廣告

    Android Kotlin 基本語法4

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

    本篇

    比較偏向一些小技巧的使用
    1. 為基礎類型新增函式
    2. Abstract技巧使用
    3. throw使用方法
    4. 利用let特性處理資料型態?
    5. 快速初始化Array
    6. 快速將兩個資料交換
    7. 自定義待處理的fun
    8. 幫loop設定標籤

  • 1. 為基礎類型新增函式
  • private fun String.clearSpace(): String = replace(" ", "")
    @Test
    fun test() {
        val string = "A B C D E F G".clearSpace()
        println("string = $string")//string = ABCDEFG
    }
    

  • 2. Abstract技巧使用
  • abstract class MyAbstractClass {
        var value: Int = -1
            set(value) {
                if(value > 0) {
                    field = value
                    success()
                } else {
                    field = -1
                    error()
                }
            }
        abstract fun success()
        abstract fun error()
    }
    @Test
    fun test() {
        val myObject = object : MyAbstractClass() {
            override fun success() {
                println("success")
            }
    
            override fun error() {
                println("error")
            }
        }
        myObject.value = -1//打印error
        myObject.value = 1//打印success
    }
    

  • 3. throw使用方法
  • fun setValue(data: Any?) {
        if(data is Int) {
            println("data is Int: $data")
        } else {
            throw NumberFormatException("data is not Int")
        }
    }
    
    @Test
    fun test() {
        val data = "data String"
        var result = false
        try {
            println("try")//1.先打印此
            setValue(data)
            result = true
        } catch (e: NumberFormatException) {
            println("catch")//2.再來此
            e.printStackTrace()
        } finally {
            println("finally")//3.再來此
            //此處無論是經過try還是catch,之後都會先經過這
        }
        println("result $result")//4.result false
    }
    

  • 4. 利用let特性處理資料型態?
  • var data: String? = "Apple"
    var data2: String? = null
    @Test
    fun test() {
        data = data?.let {
            "transform $data"
        } ?: "error A"
        data2 = data2?.let {
            "transform $data"
        } ?: "error B"
        println("data = $data, data2 = $data2")
        //data = transform Apple, data2 = error B
    }
    

  • 5. 快速初始化Array
  • fun initIntArray(size: Int): IntArray {
        return IntArray(size).apply { fill(-1) }
    }
    fun initBooleanArray(size: Int): BooleanArray {
        return BooleanArray(size).apply { fill(false) }
    }
    @Test
    fun test() {
        val array = initIntArray(5)
        array.forEach { println(it) }
        /*
        -1
        -1
        -1
        -1
        -1
         */
        val array2 = initBooleanArray(5)
        array2.forEach { println(it) }
        /*
        false
        false
        false
        false
        false
         */
    }
    

  • 6. 快速將兩個資料交換
  • @Test
    fun test() {
        var a = 1
        var b = 2
        a = b.also {
            b = a
        }
        println("a = $a, b = $b")//a = 2, b = 1
    }
    

    7. 自定義待處理的fun

    fun calcTaxes(): BigDecimal = TODO("test TODO")
    @Test
    fun test() {
        //會拋出下方
        //kotlin.NotImplementedError: An operation is not 
        //implemented: test TODO
        calcTaxes()
    }
    

    8. 設定return標籤

    @Test
    fun test() {
        loop@ for (i in 1..5) {
            for (j in 1..5) {
                if (i == 2 && j == 2) break@loop
                println("i = $i, j = $j")
            }
        }
        /*
        i = 1, j = 1
        i = 1, j = 2
        i = 1, j = 3
        i = 1, j = 4
        i = 1, j = 5
        i = 2, j = 1
        */
    }
    @Test
    fun test2() {
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return 
            // non-local return directly to the caller of foo()
    
            print(it)
        }
        println("this point is unreachable")
        //打印12
    }
    @Test
    fun test3() {
        listOf(1, 2, 3, 4, 5).forEach lit@{
            if (it == 3) return@lit 
    
            print(it)
        }
        println(" done with explicit label")
        //打印1245 done with explicit label
    }
    @Test
    fun test4() {
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@forEach 
    
            print(it)
        }
        println(" done with implicit label")
        //打印1245 done with explicit label
    }
    


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


    更多相關可以參考這裡


    相關文章

    Android Kotlin 基本語法1Android Kotlin 基本語法2
    1. var 可變變數
    2. val 不可變更參數
    3. Array 用法
    4. ArrayList 用法
    5. List的filter、sort、map、forEach
    6. when 用法
    7. fun 函式用法
    8. if 表達式
    9. for 表達式
    10. 擴充函數(自定義函式)
    1. 操作符重載
    2. 資料區間用法
    3. map使用方法
    4. 內部靜態變數
    5. 靜態變數
    6. 當資料如果是?型態宣告
    7. 資料使用!!,強制將Int?轉Int
    8. data class用法
    9. 強制轉型
    10. run、with、apply、also用法
    Android Kotlin 基本語法3Android Kotlin Classes and Objects-1
    1. class多建構式
    2. 內部class用法
    3. interface
    4. enum class 用法
    5. sealed class 用法
    6. open 用法
    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的旅程,若有最新消息會通知。

    廣告

    Android Kotlin 基本語法3

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

    1. class多建構式
    2. 內部class用法
    3. interface
    4. enum class 用法
    5. sealed class 用法
    6. open 用法

  • 1. class多建構式
  • class InfoClass(
        private var name: String, 
        private var number: Int = 1
    ) {
    
        fun getInfo() {
            println("name $name, number $number")
        }
    }
    @Test
    fun test2() {
        val test = InfoClass("Apple")
        test.getInfo() //打印 name Apple, number 1
    
        val test2 = InfoClass("John", 30)
        test2.getInfo() //打印 name John, number 30
    }
    

  • 2. 內部class用法
  • class MainClass {
        var data = 10
        fun main() {
            val innerClass = InnerClass()
            data += innerClass.addFun()
            println("data = ${data}")
        }
        inner class InnerClass {
            var data = 1
            fun addFun(): Int {
                return data + 1
            }
        }
    }
    
    val mainClass = MainClass()
    mainClass.main() //打印 data = 12 
    

  • 3. Interface
  • @Test
    fun test() {
        println("execute success")
        callback.success()
    
        println("execute error")
        callback.error()
        /*
        execute success
        success
        execute error
        error
        */
    }
    val callback = object : Callback {
        override fun success() {
            println("success")
        }
    
        override fun error() {
            println("error")
        }
    
    }
    interface Callback {
        fun success()
        fun error()
    }
    

  • 4. enum class 用法
  • @Test
    fun test() {
        var tag = EnumClass.Data1.getTag()
        println(tag)//打印 0 = Data1
        tag = EnumClass.Data2.getTag()
        println(tag)//打印 1 = Data2
        tag = EnumClass.Data3.getTag()
        println(tag)//打印 2 = Data3
    
        var color = Colors.RED
        println("color = $color, color.color ${color.color}")
        //color = RED, color.color 0xFF0000
    
        color = Colors.GREEN
        println("color = $color, color.color ${color.color}")
        //color = GREEN, color.color 0x00FF00
    
        color = Colors.BLUE
        println("color = $color, color.color ${color.color}")
        //color = BLUE, color.color 0x0000FF
    
    }
    enum class EnumClass(private val index: Int) {
        Data1(0),
        Data2(1),
        Data3(2);
        fun getTag(): String {
            return "$index = $name"
        }
    }
    
    enum class Colors(val color: String) {
        RED("0xFF0000"),
        GREEN("0x00FF00"),
        BLUE("0x0000FF")
    }
    
    enum class RGB { RED, GREEN, BLUE }
    
    inline fun <reified T : Enum> printAllValues() {
        print(enumValues().joinToString { it.name })
    }
    
    @Test
    fun test() {
        printAllValues() // 输出 RED, GREEN, BLUE
        //enum都有 name: String與 ordinal: Int
    }
    

  • 5. sealed class 用法
  • //密封類不允許有非-private 構造函數(其構造函數默認為 private)
    sealed class SealedClass {
        data class onFinished(val data: Int): SealedClass()
        object onError: SealedClass()
    }
    
    fun createSealedClass(index: Int): SealedClass {
        when(index) {
            0 -> {
                return SealedClass.onFinished(30)
            }
            else -> {
                return SealedClass.onError
            }
        }
    }
    
    @Test
    fun test() {
        val sealedClass = createSealedClass(0)
        when(sealedClass) {
            SealedClass.onError -> {
    
            }
            //data class 這裡需要使用 is
            is SealedClass.onFinished -> {
                //打印 30
                println("data = ${sealedClass.data}")
            }
        }
    }
    

  • 6. open 用法
  • //open class 才可以給class繼承
    //open fun 才可以繼承方法改寫
    open class BaseClass {
        open fun test1(value: Int) {
            //打印 BaseClass test1 20
            println("BaseClass test1 $value")
        }
        fun test2(value: Int) {
            //打印 BaseClass test2 25
            println("BaseClass test2 $value")
        }
    }
    //使用override繼承
    class TextClass: BaseClass() {
        override fun test1(value: Int) {
            super.test1(value)
            //打印 TextClass test1 30
            println("TextClass test1 ${value+10}")
        }
    }
    @Test
    fun test() {
        val testClass = TextClass()
        testClass.test1(20)
        testClass.test2(25)
    }
    //最後打印
    /*
    BaseClass test1 20
    TextClass test1 30
    BaseClass test2 25
    */
    


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


    更多相關可以參考這裡


    相關文章

    Android Kotlin 基本語法1Android Kotlin 基本語法2
    1. var 可變變數
    2. val 不可變更參數
    3. Array 用法
    4. ArrayList 用法
    5. List的filter、sort、map、forEach
    6. when 用法
    7. fun 函式用法
    8. if 表達式
    9. for 表達式
    10. 擴充函數(自定義函式)
    1. 操作符重載
    2. 資料區間用法
    3. map使用方法
    4. 內部靜態變數
    5. 靜態變數
    6. 當資料如果是?型態宣告
    7. 資料使用!!,強制將Int?轉Int
    8. data class用法
    9. 強制轉型
    10. run、with、apply、also用法
    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的旅程,若有最新消息會通知。

    廣告

    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的旅程,若有最新消息會通知。

    廣告

    Android Kotlin 基本語法1

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

    1. var 可變變數
    2. val 不可變更參數
    3. Array 用法
    4. ArrayList 用法
    5. List的filter、sort、map、forEach
    6. when 用法
    7. fun 函式用法
    8. if 表達式
    9. for 表達式
    10. 擴充函數(自定義函式)

  • 1. var 可變變數
  • var data: Int = 0
    data = 1//正確
    lateinit var: Int //稍後在初始化,但使用前必須先初始化,否則會閃退
    
    private var data1 = ""
    //在set、get變更data1資料,請用field,否則會出問題
    set(value)  {
        field = "$value plus"
        println("set data $field")
    } get() = run {
        "AA-$field"
    }
    
    @Test
    fun test1() {
        println("into $data1")
        data1 = "Apple"
        println("into $data1")
        /*打印下方
        into AA-
        set data Apple plus
        into AA-Apple plus
        */
    }
    

  • 2. val 不可變更參數
  • val data: String = “123”
    data = “123434”//錯誤,val不可set
    
    private val data get() = run {
        println("is data O")
        "123"
    }
    @Test
    fun test1() {
        println("into $data")
        //打印 
        /*is data O
        into 123*/
    }
    

  • 3. Array 用法
  • var array:Array = arrayOf('1','2','3','4','5')//建立
    //array.forEach遍歷所有array
    array.forEach { println("$it") }//此時打印出1 2 3 4 5
    array = array.plus('6')//新增
    array.forEach { println("$it") }//此時打印出1 2 3 4 5 6
    array.reverse()//資料翻轉
    array.forEach { println("$it") }//此時打印出6 5 4 3 2 1
    //遍歷的另一種方法,此方法可以知道index,也可以知道value
    for((index,value) in array.withIndex()) {
        println("$index -> $value")
    }
    

  • 4. ArrayList 用法
  • fun onArrayListChange() {
        //MutableList是可讀可寫的List,底層其實是Java的ArrayList
        //List則是可讀不可寫
        //建立ArrayList
        //var arrayList: ArrayList = arrayListOf()
        //建立MutableListOf
        var arrayList: MutableList = arrayListOf()
        arrayList.add("123")//新增123
        arrayList.add("234")//新增234
        arrayList.add(0,"aaa")//在list index = 0 位置新增aaa
        println("AA -> $arrayList")//AA -> [aaa, 123, 234]
        arrayList.removeAt(0)//刪除位置index = 0的資料
        println("BB -> $arrayList")//BB -> [123, 234]
        arrayList.clear()
        println("CC -> $arrayList")//CC -> []
    
    
        val list1 = listOf("123", "234")
        val list[0] = "233"//錯誤,List不能寫只能讀
        val list2 = List(2) {
            when(it) {
                0 -> {
                    10
                }
                1 -> {
                    15
                }
                else -> {
                    -1
                }
            }
        }
        println("${list2[0]}, ${list2[1]}")
        //打印出10, 15
    }
    

  • 5. List的filter、sort、map、forEach
  • val list = listOf("cat", "dog", "rabbit")
        .filter {
            it.endsWith("t")
        }
    println("list $list")//list [cat, rabbit]
    val list2 = listOf("dog", "cat", "rabbit")
        .sortedBy {
            it
        }
    println("list2 $list2")//list2 [cat, dog, rabbit]
    val list3 = listOf("dog", "cat", "rabbit")
        .sortedByDescending {
            it
        }
    println("list3 $list3")//list3 [rabbit, dog, cat]
    val list4 = listOf("cat", "dog", "rabbit")
        .map {
            //遍歷,並把所有換成大寫
            it.uppercase()
        }
    println("list4 $list4")//list4 [CAT, DOG, RABBIT]
    val list5 = listOf("cat", "dog", "rabbit")
    list5.forEach {
            //遍歷,並打印,map才能針對資料直接變化,forEach並不行
            println(it)
            /*
            cat
            dog
            rabbit
             */
        }
    println("list5 $list5")//list5 [cat, dog, rabbit]
    

  • 6. when 用法
  • //第一種
    val string = "123"
    when(string) {
        "123",
        "1233" -> {
    
        }
        else -> {
        }
    }
    //第二種
    val string = "123"
    val string1 = "234"
    when {
        string == "123" && string1 == "234" -> {
    
        }
        else -> {
    
        }
    }
    //第三種
    val data: Int? = 100
    when(data) {
        is Int -> {
    
        }
        in 0..100 -> {
    
        }
    }
    

  • 7. fun 函式用法
  • //第一種
    fun sum(a: Int, b: Int): Int {
        return a+b
    }
    println("${sum(1,2)}")//打印3
    //第二種
    fun sum(a: Int, b: Int) =  a + b
    println("${sum(1,2)}")//打印3
    //第三種
    fun sum(a: Int = 5, b: Int) =  a + b
    println("${sum(b=2)}")//打印7
    //第四種
    var sum = {arg1: Int, arg2: Int ->
        arg1 + arg2
    }
    println("${sum(100,10)}")//打印110
    //第五種(進階用法)
    fun calculationFun():() -> Unit {
        var data1 = 10
        var data2 = 20
        return {
            data1-=1
            data2+=2
            println("data1 = $data1, data2 = $data2")
        }
    }
    val calculationFun1 = calculationFun()
    calculationFun1() //打印data1 = 9, data2 = 22
    calculationFun1() //打印data1 = 8, data2 = 24
    

  • 8. if 表達式
  • //如果string == "123", result = 0
    //如果string == "234", result = 1
    //如果其他的話, result = 2
    val result = if(string == "123") {
        0
    } else if(string == "234") {
        1
    } else {
        2
    }
    

  • 9. for 表達式
  • val items = listOf("data1", "data2", "data3")
    //此方式,可以直接取到該index裡面的值
    for (item in items) {
        println("item = ${item}")
    }
    //此方法,可以直接取得當前index
    for (index in items.indices) {
        println("item = ${items[index]}")
    }
    
    //如果重複的話,也可以用下方
    repeat(7) { index ->
        println("index = $index")
    }
    

  • 10. 擴充函數(自定義函式)
  • class TestClass {
        private val addPrice = 100
        infix fun addPrice(value: Int): Int {
            return value+addPrice
        }
    }
    
    val testClass = TestClass()
    val result = testClass addPrice 1
    println("result = ${result}")//打印出101
    

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


    更多相關可以參考這裡


    相關文章

    Android Kotlin 基本語法2Android Kotlin 基本語法3
    1. 操作符重載
    2. 資料區間用法
    3. map使用方法
    4. 內部靜態變數
    5. 靜態變數
    6. 當資料如果是?型態宣告
    7. 資料使用!!,強制將Int?轉Int
    8. data class用法
    9. 強制轉型
    10. run、with、apply、also用法
    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. 將舊方法棄用

    歡迎訂閱唷!

    廣告

    透過 WordPress.com 建置的網站.

    向上 ↑