Android Geliştirmeyi Artıracak On Kotlin Özelliği

Yayınlanan: 2022-03-11

Tanıtım

Bir süre önce Tomasz, Android'de Kotlin geliştirmesini tanıttı. Size hatırlatmak gerekirse: Kotlin, en popüler Java IDE'lerinden biri olan IntelliJ IDEA'nın arkasındaki şirket olan Jetbrains tarafından geliştirilen yeni bir programlama dilidir. Java gibi, Kotlin de genel amaçlı bir dildir. Java Sanal Makinesi (JVM) bayt koduna uyduğundan, Java ile yan yana kullanılabilir ve bir performans yükü getirmez.

Bu yazıda, Android geliştirmenizi hızlandırmak için en iyi 10 kullanışlı özelliği ele alacağım.

Not : Bu makalenin yazıldığı sırada gerçek sürümler Android Studio 2.1.1 idi. ve Kotlin 1.0.2.

Kotlin

Hiç bitmeyen Java kodundan bıktınız mı? Kotlin'i deneyin ve zamandan ve akıl sağlığınızdan tasarruf edin.
Cıvıldamak

Kotlin Kurulumu

Kotlin, JetBrains tarafından geliştirildiğinden, hem Android Studio hem de IntelliJ'de iyi desteklenmektedir.

İlk adım Kotlin eklentisini kurmaktır. Bunu başarıyla yaptıktan sonra, Java'nızı Kotlin'e dönüştürmek için yeni eylemler mevcut olacaktır. İki yeni seçenek:

  1. Yeni bir Android projesi oluşturun ve projede Kotlin'i kurun.
  2. Mevcut bir Android projesine Kotlin desteği ekleyin.

Yeni bir Android projesinin nasıl oluşturulacağını öğrenmek için adım adım resmi kılavuza bakın. Yeni oluşturulan veya mevcut bir projeye Kotlin desteği eklemek için Mac'te Command + Shift + A veya Windows/Linux'ta Ctrl + Shift + A kullanarak bul eylemi iletişim kutusunu açın ve Configure Kotlin in Project eylemini çalıştırın.

Yeni bir Kotlin sınıfı oluşturmak için şunu seçin:

  • File > New > Kotlin file/class veya
  • File > New > Kotlin activity

Alternatif olarak, bir Java sınıfı oluşturabilir ve yukarıda belirtilen eylemi kullanarak onu Kotlin'e dönüştürebilirsiniz. Herhangi bir sınıfı, arabirimi, numaralandırmayı veya ek açıklamayı dönüştürmek için kullanabileceğinizi unutmayın ve bu, Java'yı Kotlin koduyla kolayca karşılaştırmak için kullanılabilir.

Çok fazla yazmadan tasarruf sağlayan bir başka kullanışlı unsur da Kotlin uzantılarıdır. Bunları kullanmak için build.gradle dosyanıza başka bir eklenti uygulamanız gerekir:

 apply plugin: 'kotlin-android-extensions'

Uyarı : projenizi kurmak için Kotlin eklenti eylemini kullanıyorsanız, aşağıdaki kodu en üst düzey build.gradle dosyanıza koyacaktır:

 buildscript { ext.kotlin_version = '1.0.2' repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }

Bu, uzantının çalışmamasına neden olur. Bunu düzeltmek için, bu kodu Kotlin'i kullanmak istediğiniz proje modüllerinin her birine kopyalamanız yeterlidir.

Her şeyi doğru ayarlarsanız, uygulamanızı standart bir Android projesinde yaptığınız gibi çalıştırabilir ve test edebilirsiniz, ancak şimdi Kotlin'i kullanabilirsiniz.

Kotlin ile Zamandan Tasarruf

Öyleyse, Kotlin dilinin bazı önemli yönlerini açıklayarak ve Java yerine onu kullanarak nasıl zaman kazanabileceğinize dair ipuçları vererek başlayalım.

Özellik #1: Statik Düzen İçe Aktarma

Android'deki en yaygın ortak kodlardan biri, Etkinlikler veya Parçalar'daki görünümlerinize referanslar almak için findViewById() işlevini kullanmaktır.

Butterknife kitaplığı gibi bazı yazma işlemlerinden tasarruf sağlayan çözümler vardır, ancak Kotlin, tek bir içe aktarma ile mizanpajdaki tüm referansları içe aktarmanıza izin vererek bunu başka bir adıma atar.

Örneğin, aşağıdaki aktivite XML düzenini göz önünde bulundurun:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:andro xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="co.ikust.kotlintest.MainActivity"> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>

Ve beraberindeki aktivite kodu:

 package co.ikust.kotlintest import android.support.v7.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) helloWorldTextView.text = "Hello World!" } }

Tanımlı bir kimliğe sahip düzendeki tüm görünümlerin referanslarını almak için Android Kotlin uzantısı Anko'yu kullanın. Bu import ifadesini yazmayı unutmayın:

 import kotlinx.android.synthetic.main.activity_main.*

Kotlin'de satırların sonuna noktalı virgül yazmanız gerekmediğini unutmayın çünkü bunlar isteğe bağlıdır.

TextView , görünümün kimliğine eşit ada sahip bir TextView örneği olarak içe aktarılır. Etiketi ayarlamak için kullanılan sözdizimi sizi şaşırtmasın:

 helloWorldTextView.text = "Hello World!"

Bunu birazdan ele alacağız.

Uyarılar :

  • Doğru düzeni içe aktardığınızdan emin olun, aksi takdirde içe aktarılan Görünüm referansları null bir değere sahip olur.
  • Parçaları kullanırken, onCreateView() işlev çağrısından sonra içe aktarılan Görünüm referanslarının kullanıldığından emin olun. Düzeni onCreateView() işlevinde içe aktarın ve kullanıcı arabirimini onViewCreated() içinde ayarlamak için Görünüm referanslarını kullanın. onCreateView() yöntemi bitmeden referanslar atanmaz.

Özellik #2: Kotlin ile POJO Sınıfları Yazma

Kotlin ile en çok zaman kazandıracak bir şey, verileri tutmak için kullanılan POJO (Plain Old Java Object) sınıflarını yazmaktır. Örneğin, bir RESTful API'nin istek ve yanıt gövdesinde. RESTful API'ye dayanan uygulamalarda bunun gibi birçok sınıf olacaktır.

Kotlin'de sizin için çok şey yapılır ve sözdizimi özlüdür. Örneğin, Java'da aşağıdaki sınıfı göz önünde bulundurun:

 public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }

Kotlin ile çalışırken tekrar genel anahtar kelime yazmanız gerekmez. Varsayılan olarak, her şey genel kapsamdadır. Örneğin, bir sınıf bildirmek istiyorsanız, şunu yazmanız yeterlidir:

 class MyClass { }

Yukarıdaki Java kodunun Kotlin'deki karşılığı:

 class User { var firstName: String? = null var lastName: String? = null }

Bu, yazmaktan çok tasarruf ettiriyor, değil mi? Kotlin kodunu inceleyelim.

Kotlin çok fazla yazma tasarrufu sağlar

Kotlin'de değişkenleri tanımlarken iki seçenek vardır:

  • var anahtar sözcüğü ile tanımlanan değişken değişkenler.
  • val anahtar sözcüğü ile tanımlanan değişmez değişkenler.

Unutulmaması gereken bir sonraki şey, sözdiziminin Java'dan biraz farklı olduğudur; önce değişken adını bildirirsiniz ve ardından type ile devam edersiniz. Ayrıca, varsayılan olarak, özellikler boş olmayan türlerdir, yani null değeri kabul edemezler. null değeri kabul edecek bir değişken tanımlamak için türden sonra bir soru işareti eklenmelidir. Bu ve null-safety hakkında daha sonra Kotlin'de konuşacağız.

Unutulmaması gereken bir diğer önemli nokta ise Kotlin'in sınıf için alan bildirme yeteneğinin olmamasıdır; sadece özellikler tanımlanabilir. Bu durumda, firstName ve lastName , varsayılan alıcı/ayarlayıcı yöntemlerine atanmış özelliklerdir. Belirtildiği gibi, Kotlin'de ikisi de varsayılan olarak herkese açıktır.

Özel erişimciler yazılabilir, örneğin:

 class User { var firstName: String? = null var lastName: String? = null val fullName: String? get() firstName + " " + lastName }

Dışarıdan, sözdizimi söz konusu olduğunda, özellikler Java'daki genel alanlar gibi davranır:

 val userName = user.firstName user.firstName = "John"

Yeni fullName özelliğinin salt okunur olduğunu ( val anahtar sözcüğüyle tanımlanır) ve özel bir alıcıya sahip olduğunu unutmayın; sadece adı ve soyadını ekler.

Kotlin'deki tüm özellikler, bildirildiğinde veya bir kurucudayken atanmalıdır. Bunun uygun olmadığı bazı durumlar vardır; örneğin, bağımlılık enjeksiyonu yoluyla başlatılacak özellikler için. Bu durumda, bir lateinit değiştirici kullanılabilir. İşte bir örnek:

 class MyClass { lateinit var firstName : String; fun inject() { firstName = "John"; } }

Mülkler hakkında daha fazla ayrıntı resmi belgelerde bulunabilir.

Özellik #3: Sınıf Kalıtımı ve Oluşturucular

Yapıcılar söz konusu olduğunda da Kotlin'in daha özlü bir sözdizimi vardır.

yapıcılar

Kotlin sınıfları bir birincil kurucuya ve bir veya daha fazla ikincil kurucuya sahiptir. Birincil kurucu tanımlamaya bir örnek:

 class User constructor(firstName: String, lastName: String) { }

Birincil kurucu, sınıf tanımında sınıf adından sonra gelir. Birincil kurucunun ek açıklamaları veya görünürlük değiştiricileri yoksa, kurucu anahtar sözcüğü atlanabilir:

 class Person(firstName: String) { }

Birincil kurucunun herhangi bir kodu olamayacağına dikkat edin; init kodu bloğunda herhangi bir başlatma yapılmalıdır:

 class Person(firstName: String) { init { //perform primary constructor initialization here } }

Ayrıca, özellikleri tanımlamak ve başlatmak için birincil bir kurucu kullanılabilir:

 class User(var firstName: String, var lastName: String) { // ... }

Tıpkı normal özellikler gibi, birincil kurucudan tanımlanan özellikler değişmez ( val ) veya değişebilir ( var ) olabilir.

Sınıfların ikincil kurucuları da olabilir; birini tanımlamak için sözdizimi aşağıdaki gibidir:

 class User(var firstName: String, var lastName) { constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }

Her ikincil kurucunun bir birincil kurucuya yetki vermesi gerektiğini unutmayın. Bu, this anahtar sözcüğü kullanan Java'ya benzer:

 class User(val firstName: String, val lastName: String) { constructor(firstName: String) : this(firstName, "") { //... } }

Sınıfları başlatırken, Kotlin'in Java'da olduğu gibi new anahtar sözcükleri olmadığını unutmayın. Yukarıda bahsedilen User sınıfını başlatmak için şunu kullanın:

 val user = User("John", "Doe)

Kalıtımın Tanıtılması

Kotlin'de tüm sınıflar, Java'daki Object benzer şekilde Any öğesinden uzanır. Varsayılan olarak, sınıflar, Java'daki son sınıflar gibi kapalıdır. Bu nedenle, bir sınıfı genişletmek için open veya abstract olarak bildirilmesi gerekir:

 open class User(val firstName, val lastName) class Administrator(val firstName, val lastName) : User(firstName, lastName)

Java'da yeni bir sınıfın oluşturucusunda super() yönteminin çağrılmasına benzer şekilde, genişletilmiş sınıfın varsayılan yapıcısına temsilci atamanız gerektiğini unutmayın.

Sınıflar hakkında daha fazla ayrıntı için resmi belgelere bakın.

Özellik #4: Lambda İfadeleri

Java 8 ile tanıtılan Lambda ifadeleri, favori özelliklerinden biridir. Ancak, Android'de işler o kadar parlak değil, çünkü hala yalnızca Java 7'yi destekliyor ve Java 8 yakın zamanda desteklenmeyecek gibi görünüyor. Bu nedenle, Retrolambda gibi geçici çözümler, lambda ifadelerini Android'e getirir.

Kotlin ile ek kitaplıklar veya geçici çözümler gerekmez.

Kotlin'deki İşlevler

Kotlin'deki fonksiyon sözdizimini hızlıca gözden geçirerek başlayalım:

 fun add(x: Int, y: Int) : Int { return x + y }

Fonksiyonun dönüş değeri atlanabilir ve bu durumda fonksiyon Int değerini döndürür. Kotlin'deki her şeyin Any öğesinden genişletilmiş bir nesne olduğunu ve ilkel türlerin olmadığını tekrarlamaya değer.

İşlevin bir argümanı varsayılan bir değere sahip olabilir, örneğin:

 fun add(x: Int, y: Int = 1) : Int { return x + y; }

Bu durumda, yalnızca x argümanı iletilerek add() işlevi çağrılabilir. Eşdeğer Java kodu şöyle olacaktır:

 int add(int x) { Return add(x, 1); } int add(int x, int y) { return x + y; }

Bir işlevi çağırırken bir başka güzel şey de, adlandırılmış argümanların kullanılabilmesidir. Örneğin:

 add(y = 12, x = 5)

İşlevler hakkında daha fazla ayrıntı için resmi belgelere bakın.

Kotlin'de Lambda İfadelerini Kullanma

Kotlin'deki Lambda ifadeleri, Java'da anonim işlevler olarak görüntülenebilir, ancak daha kısa bir sözdizimi ile. Örnek olarak Java ve Kotlin'de tıklama dinleyicisinin nasıl uygulanacağını gösterelim.

Java'da:

 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "Clicked on view", Toast.LENGTH_SHORT).show(); } };

Kotlin'de:

 view.setOnClickListener({ view -> toast("Click") })

Vay! Sadece bir kod satırı! Lambda ifadesinin küme parantezleri ile çevrili olduğunu görebiliriz. Önce parametreler belirtilir ve gövde -> işaretinden sonra gelir. Tıklama dinleyicisi ile, çıkarılabileceğinden görünüm parametresi için tür belirtilmez. Gövde basitçe, Kotlin'in sağladığı tost göstermek için toast() işlevine yapılan bir çağrıdır.

Ayrıca, parametreler kullanılmıyorsa, bunları dışarıda bırakabiliriz:

 view.setOnClickListener({ toast("Click") })

Kotlin, Java kitaplıklarını optimize etmiştir ve bir bağımsız değişken için tek bir yöntemle bir arabirim alan herhangi bir işlev, bir işlev bağımsız değişkeniyle (Arayüz yerine) çağrılabilir.

Ayrıca, fonksiyon son parametre ise, parantezlerin dışına taşınabilir:

 view.setOnClickListener() { toast("Click") }

Son olarak, işlevin işlev olan yalnızca bir parametresi varsa, parantezler dışarıda bırakılabilir:

 view.setOnClickListener { toast("Click") }

Daha fazla bilgi için Antonio Leiva'nın Android geliştiricileri için Kotlin kitabına ve resmi belgelere bakın.

Uzantı İşlevleri

Kotlin, C#'a benzer şekilde, uzantı işlevlerini kullanarak mevcut sınıfları yeni işlevlerle genişletme olanağı sağlar. Örneğin, bir String öğesinin MD5 karmasını hesaplayacak bir uzatma yöntemi:

 fun String.md5(): ByteArray { val digester = MessageDigest.getInstance("MD5") digester.update(this.toByteArray(Charset.defaultCharset())) return digester.digest() }

İşlev adından önce genişletilmiş sınıfın adının (bu durumda, String ) geldiğine ve genişletilmiş sınıfın örneğinin this anahtar kelime aracılığıyla erişilebilir olduğuna dikkat edin.

Uzantı işlevleri, Java yardımcı program işlevlerinin eşdeğeridir. Java'daki örnek işlev şöyle görünür:

 public static int toNumber(String instance) { return Integer.valueOf(instance); }

Örnek işlev, bir Utility sınıfına yerleştirilmelidir. Bunun anlamı, genişletme işlevlerinin orijinal genişletilmiş sınıfı değiştirmediği, ancak yardımcı program yöntemleri yazmanın uygun bir yolu olduğudur.

Özellik #5: Sıfır güvenlik

Java'da en çok uğraştığınız şeylerden biri muhtemelen NullPointerException . Null-güvenlik, Kotlin diline entegre edilmiş bir özelliktir ve o kadar örtüktür ki, genellikle endişelenmenize gerek kalmaz. Resmi belgeler, NullPointerExceptions olası tek nedeninin şunlar olduğunu belirtir:

  • NullPointerException atmak için açık bir çağrı.
  • kullanarak !! operatör (ki bunu daha sonra açıklayacağım).
  • Harici Java kodu.
  • lateinit özelliğine, başlatılmadan önce yapıcıda erişilirse, bir UninitializedPropertyAccessException oluşturulur.

Varsayılan olarak, açıkça null olarak bildirilmezlerse, Kotlin'deki tüm değişkenler ve özellikler non-null değil ( null değeri tutamaz) olarak kabul edilir. Daha önce de belirtildiği gibi, bir null değeri kabul edecek bir değişken tanımlamak için, türden sonra bir soru işareti eklenmelidir. Örneğin:

 val number: Int? = null

Ancak, aşağıdaki kodun derlenmeyeceğini unutmayın:

 val number: Int? = null number.toString()

Bunun nedeni, derleyicinin null denetimler yapmasıdır. Derlemek için null bir kontrol eklenmelidir:

 val number: Int? = null if(number != null) { number.toString(); }

Bu kod başarıyla derlenecektir. Bu durumda Kotlin'in arka planda yaptığı şey, bu number if bloğu içinde nun-null ( Int yerine Int? ) haline gelmesidir.

null kontrol, güvenli arama operatörü ( ?. ) kullanılarak basitleştirilebilir:

 val number: Int? = null number?.toString()

İkinci satır, yalnızca sayı null değilse yürütülür. Ünlü Elvis operatörünü bile kullanabilirsiniz ( ?: ):

 val number Int? = null val stringNumber = number?.toString() ?: "Number is null"

?: ifadesinin solundaki ifade null değilse değerlendirilir ve döndürülür. Aksi takdirde, sağdaki ifadenin sonucu döndürülür. Bir başka güzel şey de, Elvis operatörünün sağ tarafında, bunlar Kotlin'deki ifadeler olduğundan, throw veya return kullanabilmenizdir. Örneğin:

 fun sendMailToUser(user: User) { val email = user?.email ?: throw new IllegalArgumentException("User email is null") //... }

!! Şebeke

NullPointerException Java'dakiyle aynı şekilde atılmasını istiyorsanız, bunu !! Şebeke. Aşağıdaki kod bir NullPointerException :

 val number: Int? = null number!!.toString()

Döküm

as anahtar sözcüğü kullanılarak yapılan yayın:

 val x: String = y as String

Bu, "Güvenli olmayan" yayın olarak kabul edilir, çünkü Java'nın yaptığı gibi, yayın mümkün değilse ClassCastException atar. Bir istisna atmak yerine null değeri döndüren bir "Güvenli" yayın operatörü vardır:

 val x: String = y as? String

Döküm hakkında daha fazla ayrıntı için resmi belgelerin Tip Dökümleri ve Dökümler bölümünü kontrol edin ve null güvenlik hakkında daha fazla ayrıntı için Sıfır Güvenlik bölümünü kontrol edin.

lateinit özellikleri

lateinit özelliklerinin kullanılmasının NullPointerException benzeri bir özel duruma neden olabileceği bir durum vardır. Aşağıdaki sınıfı göz önünde bulundurun:

 class InitTest { lateinit var s: String; init { val len = this.s.length } }

Bu kod uyarı vermeden derlenecektir. Ancak, bir TestClass örneği oluşturulur oluşturulmaz, başlatılmadan önce s özelliğine erişildiğinden bir UninitializedPropertyAccessException oluşturulacaktır.

Özellik #6: with() işlev

with() işlevi kullanışlıdır ve Kotlin standart kitaplığıyla birlikte gelir. Bir nesnenin birçok özelliğine erişmeniz gerekiyorsa, bazı yazımları kaydetmek için kullanılabilir. Örneğin:

 with(helloWorldTextView) { text = "Hello World!" visibility = View.VISIBLE }

Parametre olarak bir nesne ve bir uzantı işlevi alır. Kod bloğu (kıvrımlı parantezlerde), ilk parametre olarak belirtilen nesnenin uzantı işlevi için bir lambda ifadesidir.

Özellik #7: Operatör Aşırı Yüklemesi

Kotlin ile önceden tanımlanmış bir dizi operatör için özel uygulamalar sağlanabilir. Bir işleci uygulamak için, verilen ada sahip bir üye işlevi veya bir uzantı işlevi sağlanmalıdır.

Örneğin, çarpma operatörünü uygulamak için, times(argument) adında bir üye işlev veya uzantı işlevi sağlanmalıdır:

 operator fun String.times(b: Int): String { val buffer = StringBuffer() for (i in 1..b) { buffer.append(this) } return buffer.toString() }

Yukarıdaki örnek, String üzerinde ikili * operatörünün bir uygulamasını göstermektedir. Örneğin, aşağıdaki ifade bir newString değişkenine "TestTestTestTest" değerini atayacaktır:

 val newString = "Test" * 4

Uzantı işlevleri kullanılabildiğinden, tüm nesneler için operatörlerin varsayılan davranışının değiştirilebileceği anlamına gelir. Bu iki ucu keskin bir kılıçtır ve dikkatli kullanılmalıdır. Aşırı yüklenebilecek tüm operatörlerin işlev adlarının listesi için resmi belgelere bakın.

Java ile karşılaştırıldığında bir diğer büyük fark ise == ve != operatörleridir. Operatör == şu anlama gelir:

 a?.equals(b) ?: b === null

while operatörü != şu anlama gelir:

 !(a?.equals(b) ?:

Bunun anlamı, == kullanmanın Java'daki gibi bir kimlik denetimi yapmamasıdır (bir nesnenin örneklerinin aynı olup olmadığını karşılaştırın), ancak null denetimleriyle birlikte equals() yöntemiyle aynı şekilde davranır.

Kimlik kontrolü yapmak için Kotlin'de === ve !== operatörleri kullanılmalıdır.

Özellik #8: Temsil Edilen Mülkler

Bazı özellikler bazı ortak davranışları paylaşır. Örneğin:

  • İlk erişimde başlatılan tembel başlatılmış özellikler.
  • Observer modelinde Observable'ı uygulayan özellikler.
  • Ayrı alanlar olarak bir haritada saklanan özellikler.

Bu gibi durumların uygulanmasını kolaylaştırmak için Kotlin, Delegated Properties'i destekler:

 class SomeClass { var p: String by Delegate() }

Bu, p özelliği için alıcı ve ayarlayıcı işlevlerinin başka bir sınıfın, Delegate örneği tarafından işlendiği anlamına gelir.

String özelliği için bir temsilci örneği:

 class Delegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return "$thisRef, thank you for delegating '${property.name}' to me!" } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { println("$value has been assigned to '${property.name} in $thisRef.'") } }

Yukarıdaki örnek, bir özellik atandığında veya okunduğunda bir mesaj yazdırır.

Hem değiştirilebilir ( var ) hem de salt okunur ( val ) özellikler için temsilciler oluşturulabilir.

Salt okunur bir özellik için getValue yöntemi uygulanmalıdır. İki parametre alır (resmi belgelerden alınmıştır):

  • alıcı - mülk sahibinin aynı veya bir üst türü olmalıdır (uzantı özellikleri için, genişletilen türdür).
  • meta veri - KProperty<*> veya onun üst türünde olmalıdır.

Bu işlev, özellik ile aynı türü veya onun alt türünü döndürmelidir.

Değiştirilebilir bir özellik için, bir temsilcinin ek olarak aşağıdaki parametreleri alan setValue adlı bir işlev sağlaması gerekir:

  • alıcı - getValue() ile aynı.
  • meta veriler - getValue() ile aynı.
  • yeni değer - bir özellik veya onun üst tipi ile aynı tipte olmalıdır.

Kotlin ile birlikte gelen ve en yaygın durumları kapsayan birkaç standart delege vardır:

  • Tembel
  • gözlemlenebilir
  • veto edilebilir

Tembel

Tembel, parametre olarak bir lambda ifadesi alan standart bir temsilcidir. Geçirilen lambda ifadesi, getValue() yöntemi ilk kez çağrıldığında yürütülür.

Varsayılan olarak, tembel özelliklerin değerlendirilmesi senkronize edilir. Çoklu iş parçacığı ile ilgilenmiyorsanız, ekstra performans elde etmek için lazy(LazyThreadSafetyMode.NONE) { … } kullanabilirsiniz.

gözlemlenebilir

Delegates.observable() , Observer modelinde Observables gibi davranması gereken özellikler içindir. Başlangıç ​​değeri ve üç bağımsız değişkeni (özellik, eski değer ve yeni değer) olan bir işlev olmak üzere iki parametre kabul eder.

Verilen lambda ifadesi, setValue() yöntemi her çağrıldığında yürütülür:

 class User { var email: String by Delegates.observable("") { prop, old, new -> //handle the change from old to new value } }

veto edilebilir

Bu standart temsilci, bir özelliğe atanan yeni bir değerin saklanıp saklanmayacağına karar vermenizi sağlayan özel bir Gözlemlenebilir türüdür. Bir değer atamadan önce bazı koşulları kontrol etmek için kullanılabilir. Delegates.observable() ile olduğu gibi, iki parametre kabul eder: başlangıç ​​değeri ve bir fonksiyon.

Aradaki fark, işlevin bir Boole değeri döndürmesidir. true döndürürse, özelliğe atanan yeni değer saklanır veya başka bir şekilde atılır.

 var positiveNumber = Delegates.vetoable(0) { d, old, new -> new >= 0 }

Verilen örnek, yalnızca özelliğe atanan pozitif sayıları saklayacaktır.

Daha fazla ayrıntı için resmi belgelere bakın.

Özellik #9: Bir Nesneyi Haritayla Eşlemek

Yaygın bir kullanım durumu, özelliklerin değerlerini bir harita içinde depolamaktır. Bu genellikle RESTful API'lerle çalışan ve JSON nesnelerini ayrıştıran uygulamalarda olur. Bu durumda, bir harita örneği, temsilci olarak atanan bir özellik için temsilci olarak kullanılabilir. Resmi belgelerden bir örnek:

 class User(val map: Map<String, Any?>) { val name: String by map val age: Int by map }

Bu örnekte, User bir harita alan bir birincil kurucusu vardır. İki özellik, özellik adlarına eşit anahtarlar altında eşlenen değerleri haritadan alır:

 val user = User(mapOf( "name" to "John Doe", "age" to 25 ))

Yeni kullanıcı örneğinin name özelliğine “John Doe” değeri ve age özelliğine 25 değeri atanacaktır.

Bu, MutableMap ile birlikte var özellikleri için de geçerlidir:

 class MutableUser(val map: MutableMap<String, Any?>) { var name: String by map var age: Int by map }

10. Özellik: Koleksiyonlar ve İşlevsel İşlemler

Kotlin'deki lambda desteğiyle koleksiyonlar yeni bir düzeye çıkarılabilir.

Her şeyden önce, Kotlin değiştirilebilir ve değişmez koleksiyonlar arasında ayrım yapar. Örneğin, Yinelenebilir arabirimin iki sürümü vardır:

  • yinelenebilir
  • DeğişkenYinelenebilir

Aynı şey Collection , List , Set ve Map arayüzleri için de geçerlidir.

Örneğin, en az bir öğe verilen yüklemle eşleşirse, bu any işlem true değerini döndürür:

 val list = listOf(1, 2, 3, 4, 5, 6) assertTrue(list.any { it % 2 == 0 })

Koleksiyonlarda yapılabilecek kapsamlı bir işlevsel işlemler listesi için bu blog gönderisine bakın.

Çözüm

Kotlin'in sunduklarının yüzeyini henüz çizdik. Daha fazla okumak ve daha fazlasını öğrenmek isteyenler için şunları kontrol edin:

  • Antonio Leiva'nın Kotlin blog yazıları ve kitabı.
  • JetBrains'den resmi belgeler ve öğreticiler.

Özetlemek gerekirse, Kotlin, sezgisel ve özlü bir sözdizimi kullanarak yerel Android uygulamaları yazarken zamandan tasarruf etmenizi sağlar. Hala genç bir programlama dilidir, ancak bence artık üretim uygulamaları oluşturmak için kullanılacak kadar kararlı.

Kotlin kullanmanın faydaları:

  • Android Studio desteği kusursuz ve mükemmel.
  • Mevcut bir Java projesini Kotlin'e dönüştürmek kolaydır.
  • Java ve Kotlin kodu aynı projede bir arada bulunabilir.
  • Uygulamada hız yükü yoktur.

Dezavantajları:

  • Kotlin, kitaplıklarını oluşturulan .apk dosyasına ekleyecektir, böylece nihai .apk boyutu yaklaşık 300 KB daha büyük olacaktır.
  • Kötüye kullanılırsa, operatörün aşırı yüklenmesi okunamayan koda neden olabilir.
  • IDE ve Otomatik Tamamlama, Kotlin ile çalışırken saf Java Android projelerine göre biraz daha yavaş davranır.
  • Derleme süreleri biraz daha uzun olabilir.