欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Kotlin by關鍵字作用及使用介紹

 更新時間:2022年10月10日 08:54:43   作者:hudawei996  
Kotlin 中的 by 關鍵字在 Java 中是沒有的,這使我對它感到非常陌生。Kotlin 中為什么要新增 by 關鍵字呢?by 關鍵字在 Kotlin 中是如何使用的?本文會介紹 by 關鍵字的使用分類,具體的示例,Kotlin 內置的 by 使用,希望能夠幫助到大家

1.Kotlin委托

在委托模式中,兩個對象參與處理同一請求,接受請求的對象講請求委托給另外一個對象來處理。Kotlin直接支持委托模式,更加優(yōu)雅,簡潔。kotlin通過關鍵字by實現(xiàn)委托。

2.類委托

類的委托即一個類中定義的方法實際是調用另一個類的對象的方法來實現(xiàn)的。

以下實例中派生類Derived繼承了接口Base所有方法,并且委托一個傳入的Base類的對象來執(zhí)行這些方法。

//創(chuàng)建接口
interface Base {
    fun print()
}
//實現(xiàn)此接口的被委托的類
class BaseImp(val x:Int) : Base {
    override fun print() {
 
        println(x)
    }
}
//通過關鍵字by建立委托類
class Derived (b:Base):Base by b
class Main {
    companion object{
        @JvmStatic
        fun main(args: Array<String>) {
            var baseImp=BaseImp(100)
            Derived(baseImp).print()  //輸出100
        }
    }
}

在Derived聲明中,by子句表示,將b保存在Derived的對象實例內部,而且編譯器將會生成繼承自Base接口的所有方法,并將調用轉發(fā)給b。我們看看生成的java代碼。

public final class Derived implements Base {
   // $FF: synthetic field
   private final Base $$delegate_0;
   public Derived(@NotNull Base b) {
      Intrinsics.checkNotNullParameter(b, "b");
      super();
      this.$$delegate_0 = b;
   }
   public void print() {
      this.$$delegate_0.print();
   }
}

3.屬性委托

屬性委托指的是一個類的某個屬性值不是在類中直接進行定義,而是將其委托給一個代理類,從而實現(xiàn)對該類的屬性統(tǒng)一管理。

屬性委托語法格式:

val/var <屬性名>:<類型> by <表達式>

by關鍵字之后的表達式就是委托,屬性的get()方法(以及set()方法)將被委托給這個對象的getValue()和setValue()方法。屬性委托不必實現(xiàn)任何接口,但是必須提供getValue()函數(shù)(對于var屬性,還需要setValue()函數(shù))。

3.1定義一個被委托的類

該類包含getValue()方法和setValue()方法,且參數(shù)thisRef為進行委托的類的對象,prop為進行委托的屬性的對象。

//定義包含屬性委托的類
class Example {
    var p:String by Delegate()
}
//委托的類
open class Delegate {
    operator fun getValue(thisRef:Any?,property:KProperty<*>):String{
        return "$thisRef,這里委托了${property.name} 屬性"
    }
    operator fun setValue(thisRef: Any?,property: KProperty<*>,value:String){
        println("$thisRef 的 ${property.name} 屬性賦值為 $value")
    }
}
class Main {
    companion object{
        @JvmStatic
        fun main(args: Array<String>) {
            var e=Example()
            println(e.p) //訪問該屬性 調用getValue函數(shù)
            e.p="rururn" //調用setValue()函數(shù)
            println(e.p)
        }
    }
}

輸出結構為:

com.geespace.lib.kotlin.by2.Example@3f99bd52,這里委托了p 屬性
com.geespace.lib.kotlin.by2.Example@3f99bd52 的 p 屬性賦值為 rururn
com.geespace.lib.kotlin.by2.Example@3f99bd52,這里委托了p 屬性

3.2標準委托

Kotlin的標準庫已經(jīng)內置了很多工廠方法來實現(xiàn)屬性的委托。

延遲屬性Lazy

lazy()是一個函數(shù),接受一個Lambda表達式作為參數(shù),返回一個Lazy<T>實例的函數(shù),返回的實例可以作為延遲屬性的委托:第一次調用get()會執(zhí)行已傳遞給lazy()的lamda表達式并記錄結果,后續(xù)調用get()只是返回記錄的結果。

class LazyTest {
    companion object{
        val lazyValue:String by lazy {
            println("computed!") //第一次調用輸出,第二次調用不執(zhí)行
            "Hello"
        }
        @JvmStatic
        fun main(args: Array<String>) {
            println(lazyValue)
            println(lazyValue)
        }
    }
}

執(zhí)行輸出結果:

computed!
Hello
Hello

3.3把屬性存儲在映射中

一個常見的用例是在一個映射(map)里存儲屬性的值。這經(jīng)常出現(xiàn)在像解析JSON或者其他"動態(tài)"事情的應用中。這種情況下,你可以使用映射實例自身作為委托來實現(xiàn)委托屬性。

class Site(val map:Map<String,Any?>) {
    val name:String by map
    val url:String by map
}
class TestMain {
    companion object{
        @JvmStatic
        fun main(args: Array<String>) {
            val site=Site(mapOf(
                "name" to "maozh",
                "url"  to "www.baidu.com"
            ))
            //讀取映射值
            println(site.name)
            println(site.url)
        }
    }
}

執(zhí)行輸出結果:

maozh
www.baidu.com

3.4Not Null

notNull適用于那些無法在初始化階段就確定屬性值的場合。

class Foo{
     var notNullBar:String by Delegates.notNull<String>()
}
foo.notNullBar="bar"
println(foo.notNullBar)

需要注意,如果屬性在賦值前就被訪問的話則會拋出異常。

到此這篇關于Kotlin by關鍵字作用及使用介紹的文章就介紹到這了,更多相關Kotlin by關鍵字內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論