Malay (Melayu) translation by Kaustina Nurul Ilmi (you can also view the original English article)
Kotlin adalah bahasa pengaturcaraan moden yang dikompilasi oleh Java bytecode. Bahasa pengaturcaraan ini adalah sumber bebas dan terbuka , dan berjanji untuk membuat pengekodan untuk Android lebih menyeronokkan.
Dalam artikel sebelumnya , anda belajar tentang pakej dan fungsi asas di Kotlin. Fungsi ini terletak di hati Kotlin, jadi dalam jawatan ini kita akan melihatnya dengan lebih dekat. Kami akan meneroka jenis-jenis fungsi berikut di Kotlin:
- Fungsi Tahap Teratas
- Ekspresi Lambda atau Literal Function
- Fungsi Anonim
- Fungsi Setempat atau Nested
- Fungsi Infix
- Fungsi Ahli
Anda akan kagum dengan semua perkara yang sejuk yang boleh anda lakukan dengan fungsi di Kotlin!
1. Fungsi Teratas
Fungsi Tahap Teratas adalah fungsi dalam pakej Kotlin yang ditakrifkan di luar mana-mana kelas, objek, atau antara muka. Ini bermakna bahawa mereka adalah fungsi yang anda panggil terus, tanpa perlu membuat objek atau memanggil mana-mana kelas.
Sekiranya anda seorang coder Java, anda tahu bahawa kami biasanya membuat kaedah statik utiliti dalam kelas penolong. Kelas penolong ini tidak melakukan apa-apa - mereka tidak mempunyai
syarat atau kaedah contoh, dan mereka hanya bertindak sebagai bekas
untuk kaedah statik. Contohnya adalah kelas Collections
dalam pakej java.util
dengan kaedah statik.
Fungsi peringkat teratas di Kotlin boleh digunakan dan bukannya kaedah utiliti statik dalam kelas penolong yang kami buat di Jawa. Mari kita lihat cara untuk menentukan fungsi peringkat utama di Kotlin.
package com.chikekotlin.projectx.utils fun checkUserStatus(): String { return "online" }
Dalam kod di atas, kami menentukan pakej com.chikekotlin.projectx.utils
dalam fail yang dipanggil UserUtils.kt dan juga menentukan fungsi utiliti peringkat tinggi bernama checkUserStatus()
dalam pakej dan fail yang sama. Untuk keringkasan, fungsi yang sangat mudah ini mengembalikan rentetan "dalam talian".
Perkara seterusnya yang akan kita lakukan ialah menggunakan fungsi utiliti ini dalam pakej atau fail lain.
package com.chikekotlin.projectx.users import com.chikekotlin.projectx.utils.checkUserStatus if (checkUserStatus() == "online") { // do something }
Dalam kod sebelumnya, kami mengimport fungsi ke dalam pakej lain dan kemudian melaksanakannya! Seperti yang anda lihat, kita tidak perlu membuat rujukan objek atau kelas untuk memanggil fungsi ini.
Interoperability Java
Oleh
kerana Jawa tidak menyokong fungsi peringkat atas, kompilator Kotlin di
belakang akan membuat kelas Java, dan fungsi peringkat atas akan
ditukar kepada kaedah statik. Dalam kes ini, kelas Java yang dijana adalah UserUtilsKt
dengan kaedah statik checkUserStatus()
.
/* Java */ package com.chikekotlin.projectx.utils public class UserUtilsKt { public static String checkUserStatus() { return "online"; } }
Ini
bermakna bahawa pemanggil Java hanya boleh memanggil kaedah dengan
merujuk kepada kelas yang dihasilkannya, sama seperti kaedah statik
lain.
/* Java */ import com.chikekotlin.projectx.utils.UserUtilsKt ... UserUtilsKt.checkUserStatus()
Perhatikan bahawa kita boleh menukar nama kelas Java yang dihasilkan oleh pengkompil Kotlin menggunakan keterangan @JvmName .
@file:JvmName("UserUtils") package com.chikekotlin.projectx.utils fun checkUserStatus(): String { return "online" }
Dalam kod di atas, kami menggunakan pernyataan @JvmName
dan nyatakan nama kelas UserUtils
untuk fail yang dihasilkan. Juga ambil perhatian bahawa maklumat ini diletakkan pada permulaan fail Kotlin, sebelum definisi pakej.
Ini dapat dilihat dari Java seperti ini:
/* Java */ import com.chikekotlin.projectx.utils.UserUtils ... UserUtils.checkUserStatus()
2. Lambda Expressions
Ekspresi Lambda (atau fungsi literal) juga tidak terikat kepada entiti seperti kelas, objek, atau antara muka. Mereka boleh diluluskan sebagai argumen kepada fungsi lain yang dipanggil fungsi dengan fungsi pesanan tinggi (kita akan membincangkannya lebih lanjut dalam jawatan seterusnya). Ekspresi Lambda hanya mewakili blok fungsi, dan menggunakannya mengurangkan kekacauan dalam kod kami.
Sekiranya anda seorang Java coder, anda tahu bahawa Java 8 atau ke atas memberikan sokongan untuk ungkapan Lambda. Untuk menggunakan ungkapan Lambda dalam projek yang menyokong versi lama Jawa seperti Java 7, 6, atau 5, kita boleh menggunakan perpustakaan Retrolambda .
Salah satu perkara yang menakjubkan tentang Kotlin ialah sokongan ungkapan Lambda. Kerana lambda tidak disokong di Jawa 6 atau 7, untuk Kotlin untuk menyelaraskan dengan ini, buat kelas Jawa tanpa nama di belakang tabir. Tetapi perhatikan bahawa membuat ekspresi lambda di Kotlin sangat berbeza daripada di Jawa.
Ciri-ciri berikut lambda expressions di Kotlin:
- Mesti disertakan dengan penyokong
{}
. - Jangan kata kunci yang
fun .
- Tiada pengubah akses (peribadi, awam atau dilindungi) kerana ia tidak termasuk sebarang kelas, objek, atau antara muka
- Tiada nama fungsi. Dengan kata lain, secara anonim.
- Tiada jenis pengembalian yang dinyatakan kerana ia akan diambil oleh pengkompil.
- Parameter tidak dilampirkan oleh kurungan
() .
Dan, lebih-lebih lagi, kita dapat memberikan ungkapan lambda kepada pemboleh ubah dan kemudian melaksanakannya.
Buat Lambda Expressions
Sekarang mari kita lihat beberapa contoh ungkapan lambda. Dalam kod di bawah, kami membuat ungkapan lambda tanpa parameter dan menyatakannya sebagai pemboleh ubah message
. Kemudian kami melaksanakannya dengan memanggil message()
fungsi message() .
val message = { println("Hey, Kotlin is really cool!") } message() // "Hey, Kotlin is really cool!"
Lihat juga lihat cara memasukkan parameter pada ungkapan lambda
val message = { myString: String -> println(myString) } message("I love Kotlin") // "I love Kotlin" message("How far?") // "How far?"
Dalam kod di atas, kami membuat ungkapan lambda dengan parameter myString
, bersamaan dengan jenis parameter, String
. Seperti yang anda lihat, di hadapan jenis parameter, terdapat anak panah: ini merujuk kepada kandungan lambda. Dengan kata lain, anak panah ini memisahkan senarai parameter dari
kandungan lambda. Ringkasnya, kita boleh mengabaikan jenis parameter
(yang ditetapkan oleh pengkompil).
val message = { myString -> println(myString) } // will still compile
Untuk dapat mempunyai banyak parameter, kita boleh memisahkannya dengan koma. Dan ingatlah, kami tidak membungkus senarai parameter dalam kurungan seperti di Jawa.
val addNumbers = { number1: Int, number2: Int -> println("Adding $number1 and $number2") val result = number1 + number2 println("The result is $result") } addNumbers(1, 3)
Walau bagaimanapun, ambil perhatian bahawa jika jenis parameter tidak dapat disimpulkan, mereka mestilah dinyatakan secara eksplisit (seperti dalam contoh ini), jika tidak kod tidak akan disusun.
Adding 1 and 3 The result is 4
Langkau Lambda berfungsi
Kita
boleh lulus ekspresi lambda sebagai parameter kepada fungsi: ini
dipanggil fungsi pesanan tinggi, kerana fungsi dalam fungsi itu. Jenis fungsi ini boleh menerima fungsi lambda atau anonim sebagai parameter: contohnya, fungsi pengumpulan last()
.
Dalam kod di bawah, kami meluluskan ungkapan lambda kepada fungsi last()
. (Jika anda ingin penjelasan mengenai pengumpulan di Kotlin, lawati tutorial ketiga dalam siri ini. ) Seperti namanya, ia mengembalikan elemen terakhir dalam senarai. Fungsi last()
menerima ungkapan lambda sebagai parameter, dan ungkapan ini pula mengambil argumen jenis String
.
Fungsi berfungsi sebagai predikat untuk mencari dalam subset elemen
dalam koleksi. Ini bermakna ungkapan lambda akan menentukan unsur
pengumpulan yang perlu dipertimbangkan ketika mencari yang terakhir.
val stringList: List<String> = listOf("in", "the", "club") print(stringList.last()) // will print "club" print(stringList.last({ s: String -> s.length == 3})) // will print "the"
Mari kita lihat cara membuat kod di atas lebih mudah dibaca.
stringList.last { s: String -> s.length == 3 } // will also compile and print "the"
Pengkompil Kotlin membolehkan kita memadamkan fungsi kurungan jika hujah terakhir dalam fungsinya adalah ungkapan lambda.
Seperti yang anda boleh perhatikan dalam kod di atas, kita boleh
lakukan ini kerana hujah terakhir dan satu-satunya yang dihantar ke
fungsi last()
adalah ungkapan lambda.
Seterusnya, kita boleh menjadikannya lebih ringkas dengan mengeluarkan parameter jenis.
stringList.last { s -> s.length == 3 } // will also compile print "the"
Kita tidak perlu menentukan jenis parameter dengan jelas, kerana jenis parameter sentiasa sama dengan jenis elemen pengumpulan. Dalam kod di atas, kita memanggil last
koleksi koleksi objek String
, jadi pengkompil Kotlin akan mengetahui bahawa parameter itu juga akan menjadi jenis String
.
Nama hujah
Kami
juga dapat mempermudah ekspresi lambda dengan menggantikan hujah
ungkapan lambda yang dijana secara automatik dengan nama argumen lalai, it
.
stringList.last { it.length == 3 }
Argumen it
dijana secara automatik kerana yang last
dapat menerima ungkapan lambda atau fungsi anonim (kita akan
melakukannya) dengan hanya satu argumen, dan jenis tersebut dapat
disimpulkan oleh pengkompil.
Pulangan Tempatan mengenai Lambda Expressions
Mari kita mulakan dengan contoh. Dalam kod di bawah, kami meluluskan ungkapan lambda kepada fungsi foreach()
dipanggil dalam koleksi intList
. Fungsi ini akan lulus koleksi dan laksanakan lambda pada setiap elemen
dalam senarai. Sekiranya terdapat elemen yang boleh dibahagikan dengan
2, ia akan berhenti dan kembali dari lambda.
fun surroundingFunction() { val intList = listOf(1, 2, 3, 4, 5) intList.forEach { if (it % 2 == 0) { return } } println("End of surroundingFunction()") } surroundingFunction() // nothing happened
Menjalankan kod di atas mungkin tidak memberikan hasil yang anda harapkan. Ini kerana penyata pulangan tidak akan kembali dari lambda tetapi dari surroundingFunction()
! Ini bermakna penyataan kod terakhir di surroundingFunction()
tidak akan dilaksanakan.
// ... println("End of surroundingFunction()") // This won't execute // ...
Untuk membetulkan masalah ini, kita perlu menyatakan secara jelas fungsi mana yang akan dikembalikan menggunakan label atau tag nama.
fun surroundingFunction() { val intList = listOf(1, 2, 3, 4, 5) intList.forEach { if (it % 2 == 0) { return@forEach } } println("End of surroundingFunction()") // Now, it will execute } surroundingFunction() // print "End of surroundingFunction()"
Dalam kod dikemaskini di atas, kami nyatakan tag @forEach
lalai selepas perkataan return
dalam lambda. Kami kini mengarahkan pengkompil untuk mengembalikan lambda, bukan
surroundingFunction()
. Sekarang, kenyataan terakhir
surroundingFunction()
akan dilaksanakan.
Perhatikan bahawa kami juga boleh menentukan label atau nama namaku sendiri.
// ... intList.forEach myLabel@ { if (it % 2 == 0) { return@myLabel // ...
Dalam kod di atas, kami menentukan label kami bernama myLabel@
dan nyatakannya sebagai return
. label @forEach
dihasilkan oleh pengkompil untuk fungsi forEach
tidak lagi tersedia kerana kami telah menentukannya sendiri.
Walau bagaimanapun, anda akan melihat bagaimana masalah pulangan tempatan ini dapat diselesaikan tanpa label apabila kita membincangkan Fungsi Anonim kemudian di Kotlin.
3. Fungsi Ahli
Jenis fungsi ini ditakrifkan dalam kelas, objek, atau antara muka. Dengan menggunakan fungsi ahli, kami boleh membuat modularize program kami dengan lebih lanjut. Mari kita lihat cara membuat fungsi ahli.
class Circle { fun calculateArea(radius: Double): Double { require(radius > 0, { "Radius must be greater than 0" }) return Math.PI * Math.pow(radius, 2.0) } }
Kod ini menunjukkan kelas Circle
(kita akan membincangkan kelas Kotlin dalam jawatan seterusnya) yang mempunyai fungsi ahli calculateArea()
. Fungsi ini mempunyai parameter radius
untuk mengira kawasan bulatan.
Untuk
memanggil fungsi ahli, kami menggunakan nama kelas atau contoh objek
dengan mata, diikuti dengan nama fungsi, serta argumen jika perlu.
val circle = Circle() print(circle.calculateArea(4.5)) // will print "63.61725123519331"
4. Fungsi tanpa nama
Fungsi tanpa nama adalah satu lagi cara untuk menentukan blok kod yang boleh diluluskan pada fungsi. Ini tidak terikat oleh mana-mana pengecam. Berikut adalah ciri-ciri fungsi anonim di Kotlin:
- Tidak mempunyai nama
- Dibuat dengan
fun
kata kunci - Terdapat kandungan fungsi
val stringList: List<String> = listOf("in", "the", "club") print(stringList.last{ it.length == 3}) // will print "the"
Kerana kami akan lulus lambda ke fungsi last()
atas, fungsi di atas, kami tidak boleh menggunakan jenis pulangan dengan jelas. Untuk dapat melakukannya, kita perlu menggunakan fungsi anonim sebaliknya.
val strLenThree = stringList.last( fun(string): Boolean { return string.length == 3 }) print(strLenThree) // will print "the"
Dalam kod di atas, kami telah menggantikan ungkapan lambda dengan fungsi tanpa nama kerana kami ingin menggunakan jenis kembali secara eksplisit.
Menjelang akhir bahagian lambda dalam tutorial ini, kami menggunakan label untuk menentukan fungsi mana yang akan dikembalikan. Menggunakan fungsi anonim dan bukan lambda dalam fungsi forEach()
berfungsi menyelesaikan masalah dengan lebih mudah. kembali ungkapan fungsi tanpa nama dan bukannya di sekelilingnya, yang dalam kes ini adalah surroundingFunction()
.
fun surroundingFunction() { val intList = listOf(1, 2, 3, 4, 5) intList.forEach ( fun(number) { if (number % 2 == 0) { return } }) println("End of surroundingFunction()") // statement executed } surroundingFunction() // will print "End of surroundingFunction()"
5. Fungsi Tempatan atau Nested
Untuk mengambil modulasi program lagi, Kotlin memberi kita fungsi tempatan - juga dikenali sebagai fungsi bersarang. Fungsi tempatan adalah fungsi yang diisytiharkan dalam fungsi lain.
fun printCircumferenceAndArea(radius: Double): Unit { fun calCircumference(radius: Double): Double = (2 * Math.PI) * radius val circumference = "%.2f".format(calCircumference(radius)) fun calArea(radius: Double): Double = (Math.PI) * Math.pow(radius, 2.0) val area = "%.2f".format(calArea(radius)) print("The circle circumference of $radius radius is $circumference and area is $area") } printCircumferenceAndArea(3.0) // The circle circumference of 3.0 radius is 18.85 and area is 28.27
Seperti yang anda lihat dalam kod di atas, kami mempunyai dua fungsi: calCircumference()
dan calArea()
bersarang dalam fungsi printCircumferenceAndAread()
. Fungsi bersarang boleh dipanggil hanya dari dalam fungsi, bukan di luar.
Sekali lagi, penggunaan fungsi bersarang menjadikan program kami lebih
modular dan kemas.
Kita boleh membuat fungsi tempatan kita lebih ringkas dengan tidak menghantar parameter dengan jelas. Ini adalah mungkin kerana fungsi tempatan mempunyai akses kepada semua parameter dan fungsi pembolehubah. Mari lihat kod berikut:
fun printCircumferenceAndArea(radius: Double): Unit { fun calCircumference(): Double = (2 * Math.PI) * radius val circumference = "%.2f".format(calCircumference()) fun calArea(): Double = (Math.PI) * Math.pow(radius, 2.0) val area = "%.2f".format(calArea()) // ... }
Seperti yang anda dapat lihat, kod yang diperbaharui ini kelihatan lebih mudah dibaca dan dikurangkan daripada kekacauan yang kita alami sebelum ini. Walaupun fungsi dalam contoh ini diberikan kecil, dalam fungsi lebih besar yang boleh dipecah menjadi fungsi bersarang yang lebih kecil, ciri ini sangat berguna.
6. Fungsi Infix
Fungsi infix
membolehkan kami dengan mudah memanggil fungsi ahli argumen atau sambungan fungsi. Di samping fungsi menjadi satu hujah, anda juga perlu menentukan fungsi menggunakan pengubah infix
. Untuk mewujudkan fungsi infix, dua parameter terlibat. Parameter
pertama adalah objek sasaran, manakala parameter kedua hanya satu
parameter yang diserahkan kepada fungsi.
Buat Fungsi Anggota Infix
Mari lihat cara membuat fungsi infix di kelas. Dalam contoh kod di bawah, kita buat Student
kelas yang tidak tetap dengan contoh kotlinScore
. Kami mencipta fungsi infix
menggunakan pengubah infix sebelum kata kunci
fun
. Seperti yang anda lihat di bawah, kami mencipta fungsi infix
addKotlinScore()
yang menggunakan skor dan menambah nilai contoh
kotlinScore
.
class Student { var kotlinScore = 0.0 infix fun addKotlinScore(score: Double): Unit { this.kotlinScore = kotlinScore + score } }
Memanggil Fungsi Infix
Mari lihat cara untuk memanggil fungsi infix yang telah kami buat. Untuk memanggil fungsi infix di Kotlin, kita tidak perlu menggunakan notasi titik, dan kita tidak perlu membungkus parameter dengan kurungan.
val student = Student() student addKotlinScore 95.00 print(student.kotlinScore) // will print "95.0"
Dalam kod di atas, kita memanggil fungsi infix, objek sasaran adalah student
, dan didarab dengan 95.00
adalah parameter yang diluluskan dalam fungsi.
Menggunakan fungsi infix menjadikan kod kami lebih ekspresif dan lebih jelas daripada biasa. Ini sangat berguna apabila membuat unit ujian di Kotlin (kami akan membincangkan ujian di Kotlin dalam jawatan berikutnya).
"Chike" should startWith("ch") myList should contain(myElement) "Chike" should haveLength(5) myMap should haveKey(myKey)
Infix to
berfungsi
Di Kotlin, kita boleh membuat contoh Pair
lebih ringkas dengan menggunakan infix berfungsi daripada pembina Pair
. (di belakang tabir, to
juga membuat contoh Pair
) Ingat bahawa to
berfungsi juga merupakan fungsi lanjutan (kami akan membincangkannya lebih lanjut dalam jawatan berikutnya).
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
Sekarang bandingkan contoh Pair
menggunakan fungsi Pair
dan pembina, yang melakukan operasi yang sama, dan melihat mana yang lebih baik.
val nigeriaCallingCodePair = 234 to "Nigeria" val nigeriaCallingCodePair2 = Pair(234, "Nigeria") // Same as above
Seperti yang anda lihat dalam kod di atas, menggunakan to
fungsi ini adalah lebih pendek daripada menggunakan Pair
untuk membuat contoh Pair
. Ingat bahawa menggunakan infix berfungsi, 234
adalah objek sasaran dan
String
"Nigeria" adalah parameter yang diluluskan kepada fungsi.
Lebih-lebih lagi, perlu diingatkan bahawa kita juga boleh melakukan ini
untuk membuat jenis Pair
:
val nigeriaCallingCodePair3 = 234.to("Nigeria") // same as using 234 to "Nigeria"
Dalam julat Ranges dan Koleksi , kami membuat koleksi peta di Kotlin dengan memberikan beberapa senarai - nilai pertama menjadi kunci, dan nilai kedua. Mari juga bandingkan peta menggunakan kedua-duanya.to
Infix dan Pair
Pembuat Pair untuk membuat contoh pasangan.
val callingCodesMap: Map<Int, String> = mapOf(234 to "Nigeria", 1 to "USA", 233 to "Ghana")
Dalam kod di atas, kami membuat Pair
jenis Senarai dipisahkan koma menggunakan fungsi infix dan diluluskan ke fungsi mapOf()
. Kita juga boleh membuat peta yang sama secara langsung menggunakan pembina Pair
untuk setiap pasangan contoh.
val callingCodesPairMap: Map<Int, String> = mapOf(Pair(234, "Nigeria"), Pair(1, "USA"), Pair(233, "Ghana"))
Seperti yang anda lihat, infix berfungsi lebih ringkas daripada menggunakan pembina Pair
.
Kesimpulannya
Dalam tutorial ini, anda belajar tentang beberapa perkara yang boleh anda lakukan dengan fungsi di Kotlin. Iaitu:
- Fungsi Tingkat Atas
- Ekspresi Lambda atau Fungsi Literal
- Fungsi Anggota
- Fungsi Anonim
- Fungsi Setempat atau Nested
- Fungsi Infix
Tetapi itu bukan semua! Masih banyak yang perlu dipelajari mengenai fungsi di Kotlin. Oleh itu, dalam jawatan berikutnya, anda akan mempelajari beberapa kegunaan untuk fungsi lanjutan, seperti lanjutan dan fungsi pesanan tinggi. Jumpa lagi!
Untuk mengetahui lebih lanjut mengenai bahasa Kotlin, lawati Dokumentasi Kotlin . Atau lihat beberapa jawatan kami yang lain dalam pembangunan aplikasi Android di Envato Tuts +!
- Android SDKCara menggunakan API Wawasan Awan Google dalam Apl AndroidAshraff Hathibelagal
- JavaCorak Reka Bentuk Android: Corak ObserverChike Mgbemena
- Android SDKMenambah animasi berasaskan fizik ke Android AppsAshraff Hathibelagal
- Android SDKAndroid O: Pengesahan Nombor Telefon Dengan Token SMSChike Mgbemena
- Android SDKApakah Apl Android Segera?Jessica Thornsby
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post