Android için geliştirme yaparken bazen şuna benzer bir şeyle karşılaşıyorum:
var someModel: someViewModel by notNullAndObservable { vm ->
...
}
by
Anahtar kelimenin anlamını anlamıyorum .
Yanıtlar:
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.
Basit bir deyişle, by
anahtar kelimeyi tarafından sağlandığı şekilde anlayabilirsiniz .
Mülk tüketicisi açısından bakıldığında val
, alıcı (alma) olan ve var
alı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, by
anahtar 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 lazy
for 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 by
orada hayır ). '
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.
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