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

Kotlin by關(guān)鍵字作用及使用介紹

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

1.Kotlin委托

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

2.類委托

類的委托即一個類中定義的方法實際是調(diào)用另一個類的對象的方法來實現(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)
    }
}
//通過關(guān)鍵字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的對象實例內(nèi)部,而且編譯器將會生成繼承自Base接口的所有方法,并將調(diào)用轉(zhuǎn)發(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.屬性委托

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

屬性委托語法格式:

val/var <屬性名>:<類型> by <表達(dá)式>

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

3.1定義一個被委托的類

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

//定義包含屬性委托的類
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) //訪問該屬性 調(diào)用getValue函數(shù)
            e.p="rururn" //調(diào)用setValue()函數(shù)
            println(e.p)
        }
    }
}

輸出結(jié)構(gòu)為:

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標(biāo)準(zhǔn)委托

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

延遲屬性Lazy

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

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

執(zhí)行輸出結(jié)果:

computed!
Hello
Hello

3.3把屬性存儲在映射中

一個常見的用例是在一個映射(map)里存儲屬性的值。這經(jīng)常出現(xiàn)在像解析JSON或者其他"動態(tài)"事情的應(yīng)用中。這種情況下,你可以使用映射實例自身作為委托來實現(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í)行輸出結(jié)果:

maozh
www.baidu.com

3.4Not Null

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

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

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

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

相關(guān)文章

最新評論