'By' anahtar kelimesi Kotlin'de ne işe yarar?


Yanıtlar:


76

In Kotlin referans için iki kullanıma bulacaksınız by, ilk olmanın Yetki Özellikleri Yukarıda sahip kullanımıdır:

Her ihtiyaç duyduğumuzda bunları manuel olarak uygulayabilsek de, bir kez ve herkes için uygulanması ve bir kitaplığa yerleştirilmesi çok güzel olacak bazı yaygın özellik türleri vardır. Örnekler arasında tembel özellikler bulunur: değer yalnızca ilk erişimde hesaplanır, gözlemlenebilir özellikler: dinleyiciler bu özellikteki değişiklikler hakkında bildirim alır, özellikleri her biri ayrı bir alanda değil, bir haritada depolar.

Burada alıcı / ayarlayıcıyı işi yapan ve ortak kod içerebilen başka bir sınıfa atarsınız. Başka bir örnek olarak, Kotlin için bazı bağımlılık enjektörleri, alıcıyı bağımlılık enjeksiyon motoru tarafından yönetilen örneklerin kayıt defterinden bir değer almaya delege ederek bu modeli destekler.

Ve Arayüz / Sınıf yetkisi diğer kullanımdır:

Delegasyon modelinin, uygulama mirasına iyi bir alternatif olduğu kanıtlanmıştır ve Kotlin, sıfır standart kod gerektiren yerel olarak bunu desteklemektedir. Türetilmiş bir sınıf, Base arabiriminden miras alabilir ve tüm genel yöntemlerini belirtilen bir nesneye delege edebilir

Burada, bir arabirimi başka bir uygulamaya devredebilirsiniz, böylece uygulama sınıfının yalnızca değiştirmek istediği şeyi geçersiz kılması gerekirken, yöntemlerin geri kalanı daha tam bir uygulamaya geri dönebilir.

Canlı bir örnek , belirli bir koleksiyon arayüzünü gerçekten başka bir sınıfa delege ettikleri ve ardından salt okunur uygulamada farklı olması gereken her şeyi geçersiz kıldığı Klutter Salt Okunur / Değişmez koleksiyonları olabilir. Diğer tüm yöntemleri manuel olarak yetkilendirmek zorunda kalmadan çok fazla iş tasarrufu.

Bunların her ikisi de Kotlin dili referansı kapsamındadır, dilin temel konuları için buradan başlayın.


93

Basit bir deyişle, byanahtar kelimeyi tarafından sağlandığı şekilde anlayabilirsiniz .

Mülk tüketicisi açısından bakıldığında val, alıcı (alma) olan ve varalıcı ve ayarlayıcı (alma, ayarlama) olan bir şeydir. Her varözellik için, açıkça belirtmemiz gerekmeyen varsayılan bir get ve set yöntemleri sağlayıcısı vardır.

Ancak, byanahtar kelimeyi kullanırken , bu alıcı / alıcı ve ayarlayıcının başka bir yerde sağlandığını (yani yetkilendirildiğini) belirtiyorsunuz. Daha sonra gelen işlev tarafından sağlanırby .

Dolayısıyla, bu yerleşik get ve set yöntemlerini kullanmak yerine, bu işi belirli bir açık işleve atarsınız.

Çok yaygın bir örnek by lazyfor lazy loading özellikleridir. Ayrıca, Koin gibi bağımlılık enjeksiyon kitaplığı kullanıyorsanız, aşağıdaki gibi tanımlanmış birçok özellik göreceksiniz:

var myRepository: MyRepository by inject()  //inject is a function from Koin

Sınıf tanımında, aynı ilkeyi izler, bazı işlevlerin nerede sağlandığını tanımlar, ancak yalnızca get ve set değil, herhangi bir yöntem / özellik kümesine başvurabilir.

class MyClass: SomeInterface by SomeImplementation, SomeOtherInterface

Bu kod şunu söylüyor: 'Sınıfım sınıfıyım ve SomeImplementation tarafından sağlanan SomeInterface arabiriminin işlevlerini sunuyorum. SomeOtherInterface'i kendim uygulayacağım (bu örtük, yani byorada hayır ). '


23

görüntü açıklamasını buraya girin

Sözdizimi şöyledir:

val/var <property name>: <Type> by <expression>. 

Tarafından sonraki ifade, temsilcidir

biz özellik değerini erişmeye çalışırsanız p diyoruz eğer, başka bir deyişle, ) (olsun mülkiyet yöntemi p , getValue () metodu Delege örneği çağrılır.

Biz özellik değerini ayarlamak çalışırsanız p biz çağrı eğer, başka bir deyişle, () set özellik yöntemini p , setValue () metodu Delege örneği çağrılır.


7

Mülkiyet yetkisi:

import kotlin.reflect.KProperty

class Delegate {
    // for get() method, ref - a reference to the object from 
    // which property is read. prop - property
    operator fun getValue(ref: Any?, prop: KProperty<*>) = "textA"
    // for set() method, 'v' stores the assigned value
    operator fun setValue(ref: Any?, prop: KProperty<*>, v: String) {
        println("value = $v")
    }
}

object SampleBy {
    var s: String by Delegate() // delegation for property
    @JvmStatic fun main(args: Array<String>) {
        println(s)
        s = "textB"
    }
}

Sonuç:

textA
value = textB

Sınıf için yetki:

interface BaseInterface {
    val value: String
    fun f()
}

class ClassA: BaseInterface {
    override val value = "property from ClassA"
    override fun f() { println("fun from ClassA") }
}

// The ClassB can implement the BaseInterface by delegating all public 
// members from the ClassA.
class ClassB(classA: BaseInterface): BaseInterface by classA {}

object SampleBy {
    @JvmStatic fun main(args: Array<String>) {
        val classB = ClassB(ClassA())
        println(classB.value)
        classB.f()
    }
}

Sonuç:

property from ClassA
fun from ClassA

Parametreler için yetki:

// for val properties Map is used; for var MutableMap is used
class User(mapA: Map<String, Any?>, mapB: MutableMap<String, Any?>) {
    val name: String by mapA
    val age: Int by mapA
    var address: String by mapB
    var id: Long by mapB
}

object SampleBy {
    @JvmStatic fun main(args: Array<String>) {
        val user = User(mapOf("name" to "John", "age" to 30),
        mutableMapOf("address" to "city, street", "id" to 5000L))

        println("name: ${user.name}; age: ${user.age}; " +
        "address: ${user.address}; id: ${user.id}")
    }
}

Sonuç:

name: John; age: 30; address: city, street; id: 5000
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.