Indonesian (Bahasa Indonesia) translation by Imam Firmansyah (you can also view the original English article)
Kotlin adalah bahasa pemrograman modern yang mengkompilasi ke Java bytecode. Ini gratis dan open source, dan menjanjikan untuk membuat coding untuk Android semakin menyenangkan.
Pada artikel sebelumnya, Anda belajar tentang ranges dan collections di Kotlin. Dalam tutorial ini, kita akan belajar bahasa dengan melihat bagaimana mengatur kode menggunakan packages, dan kemudian melanjutkan pengenalan function di Kotlin.
1. Packages
Jika Anda sudah familiar dengan Java, Anda tahu Java menggunakan packages untuk mengelompokkan class terkait; Sebagai contoh, packages java.util
memiliki sejumlah class utilitas. Packages dideklarasikan dengan kata kunci package
, dan file Kotlin dengan deklarasi package
di awal dapat berisi deklarasi class, function, atau interface.
Deklarasi
Lihatlah kode di bawah ini, kami telah mendeklarasikan package com.chikekotlin.projectx
menggunakan kata kunci package
. Kami juga mendeklarasikan class MyClass
(kami akan membahas class di Kotlin di artikel selanjutnya) di dalam package ini.
package com.chikekotlin.projectx class MyClass
Sekarang, nama yang memenuhi syarat untuk class MyClass
adalah com.chikekotlin.projectx.MyClass
.
package com.chikekotlin.projectx fun saySomething(): String { return "How far?" }
Pada kode di atas, top-level function telah dibuat (kita akan segera melakukannya). Begitu juga dengan MyClass
, nama yang memenuhi syarat untuk function saySomething()
adalah com.chikekotlin.projectx.saySomething
.
Import
Di Kotlin, kami menggunakan deklarasi import
untuk mengaktifkan compiler untuk menemukan class, function, interface atau object yang akan diimpor. Di sisi lain, pada Java kita tidak dapat secara langsung mengimpor function atau class hanya method atau interface.
Kami menggunakan import
untuk mengakses function, interface, class atau object di luar package tempat dideklarasikan.
import com.chikekotlin.projectx.saySomething fun main(args: Array<String>) { saySomething() // will print "How far?" }
Dalam potongan kode di atas, kita mengimpor function saySomething()
dari package yang berbeda, dan kemudian kita menjalankan function tersebut.
Kotlin juga mendukung impor wildcard menggunakan operator *
. Operator akan mengimpor semua class, interface dan function yang dideklarasikan dalam package secara sekaligus. Hal ini tidak disarankan, meskipun-biasanya lebih baik membuat impor Anda eksplisit.
import com.chikekotlin.projectx.*
Import Aliasing
Bila Anda memiliki perpustakaan yang memiliki nama kelas atau function yang bertentangan (misalnya masing-masing mendeklarasikan function dengan nama yang sama), Anda dapat menggunakan kata kunci as
untuk diberikan ke entitas yang diimpor tersebut sebagai nama sementara.
import com.chikekotlin.projectx.saySomething import com.chikekotlin.projecty.saySomething as projectYSaySomething fun main(args: Array<String>) { projectYSaySomething() }
Perhatikan bahwa nama sementara hanya digunakan di dalam file yang telah ditetapkan.
2. Functions
Sebuah kelompok function dan serangkaian pernyataan kode yang melakukan tugas. Rincian pelaksanaan function disembunyikan dari pemanggil.
Di Kotlin, function didefinisikan dengan menggunakan kata kunci fun
, seperti yang ditunjukkan pada contoh berikut:
fun hello(name: String): String { return "Hello $name" } val message = hello("Chike") print(message) // will print "Hello Chike"
Pada kode yang berada di atas, kita mendefinisikan sebuah function sederhana hello()
dengan satu parameter tunggal name
dengan tipe String
. Function ini mengembalikan tipe String
. The parameter definition format for functions is name: type
, e.g. age: Int
, price: Double
, student: StudentClass
.
fun hello(name: String): Unit { print("Hello $name") } hello("Chike") // will print "Hello Chike"
Function diatas hampir mirip dengan yang sebelumnya, tapi perhatikan bahwa yang satu ini memiliki tipe pengembalian Unit
. Karena function ini tidak mengembalikan satupun nilai signifikan - hanya menampilkan pesan - secara default tipe pengembaliannya adalah Unit
. Unit
adalah sebuah object di Kotlin (kita akan membahas object Kotlin di artikel selanjutnya) yang mirip dengan tipe Void
pada Java dan C.
public object Unit { override fun toString() = "kotlin.Unit" }
Perhatikan bahwa jika Anda tidak secara eksplisit menyatakan tipe pengembalian menjadi Unit
, jenisnya akan disimpulkan oleh compiler.
fun hello(name: String) { // will still compile print("Hello $name") }
Single-Line Functions
Single-line atau one-line functions adalah function yang hanya memiliki sati ekspresi. Pada function ini kita akan mendapatkan In this function, kita menyingkirkan kurung kurawal dan menggunakan simbol =
sebelum ekspresi. Dengan kata lain, kita menyingkirkan blok function.
fun calCircumference(radius: Double): Double { return (2 * Math.PI) * radius }
Function diatas bisa dipersingkat menjadi satu baris:
fun calCircumference(radius: Double) = (2 * Math.PI) * radius
Lihatlah function yang diperbarui di atas, Anda dapat melihat bahwa kami telah membuat kode menjadi lebih singkat dengan menghapus kurung kurawal {}
, kata kunci return
, dan juga jenis pengembalian (yang disimpulkan oleh compiler).
Anda masih bisa memasukkan tipe pengembalian agar lebih eksplisit.
fun calCircumference(radius: Double): Double = (2 * Math.PI) * radius
Named Parameters
Parameter yang diberi nama memungkinkan function lebih mudah dibaca dengan memberi nama parameter yang dilewatkan ke function saat dipanggil.
Pada contoh berikut, kami membuat sebuah function yang mencetak nama lengkap.
fun sayMyFullName(firstName: String, lastName: String, middleName: String): Unit { print("My full name is $firstName $middleName $lastName"); }
Untuk menjalankan function di atas, kita dapat memanggilnnya seperti ini:
sayMyFullName("Chike", "Nnamdi", "Mgbemena")
Melihat function panggilan di atas, kita tidak tahu argumen tipe String
mana yang sesuai dengan parameter function (walaupun beberapa IDE seperti IntelliJ IDEA dapat membantu kita). Pengguna function harus melihat signature function (atau source code) atau dokumentasi untuk mengetahui parameter yang sesuai dengan masing-masing parameter.
sayMyFullName(firstName = "Chike", middleName = "Nnamdi", lastName = "Mgbemena")
Pada function kedua di atas, kami memberikan nama parameter sebelum nilai argumen. Anda dapat melihat bahwa pemanggilan function ini lebih jelas dan lebih mudah dibaca daripada yang sebelumnya. Cara memanggil function ini membantu mengurangi kemungkinan adanya bug yang bisa terjadi bila argumen dari tipe yang sama tertukar karena kesalahan.
Pemanggil juga dapat mengubah urutan parameter menggunakan parameter bernama. Sebagai contoh:
sayMyFullName(lastName = "Mgbemena", middleName = "Nnamdi", firstName = "Chike") // will still compile
Pada kode di atas, kita menukar posisi argumen dari firstName
dengan lastName
. Urutan argumen tidak masalah dengan parameter yang diberi nama karena compiler akan memetakan masing-masing parameter function dengan tepat.
Parameter Default
Di Kotlin, kita bisa memberi nilai default function untuk parameter-parameternya. Nilai default ini digunakan jika tidak ada yang ditugaskan ke argumen selama pemanggilan function. Untuk melakukan ini di Java, kita harus membuat metode kelebihan beban yang berbeda.
Pada method calCircumference()
, memodifikasi method dengan menambahkan nilai default untuk parameter pi
—Math.PI
, constant yang berada dari package java.lang.Math
fun calCircumference(radius: Double, pi: Double = Math.PI): Double = (2 * pi) * radius
Ketika kita memanggil function ini, kita dapat melewati nilai perkiraan untuk pi
atau menggunakannya secara default.
print(calCircumference(24.0)) // used default value for PI and prints 150.79644737231007 print(calCircumference(24.0, 3.14)) // passed value for PI and prints 150.72
Perhatikanlah contoh lainnya:
fun printName(firstName: String, middleName: String = "N/A", lastName: String) { println("first name: $firstName - middle name: $middleName - last name: $lastName") }
Dalam kode berikut, kita mencoba memanggil function tersebut, namun tidak akan di-compile:
printName("Chike", "Mgbemena") // won't compile
Dalam function panggilan di atas, saya melewati nama depan dan nama belakang saya ke function, dan berharap untuk menggunakan nilai default untuk nama tengah. Tapi ini tidak akan di-compile karena compiler bingung. Tidak tahu untuk apa argumen "Mgbemena" itu — apakah untuk parameter middleName
atau parameter lastName
?
Untuk memecahkan masalah tersebut, kita bisa menggabungkan named parameter dan default parameter.
printName("Chike", lastName = "Mgbemena") // will now compile
Java Interoperability
Mengingat Java tidak mendukung nilai parameter default dalam method, Anda harus menentukan semua nilai parameter secara eksplisit saat Anda memanggil function Kotlin dari Java. Tapi Kotlin memberi kita fungsionalitas untuk mempermudah dalam pemanggilan Java dengan memberi anotasi pada function Kotlin dengan @JvmOverloads
. Anotasi ini akan menginstruksikan compiler Kotlin untuk menghasilkan overloads function Java untuk kita.
Dalam contoh berikut, kami memberi beberapa function calCirumference()
dengan @JvmOverloads
.
@JvmOverloads fun calCircumference(radius: Double, pi: Double = Math.PI): Double = (2 * pi) * radius
Kode berikut dihasilkan oleh compiler Kotlin sehingga pemanggil Java tersebut dapat memilih yang mana yang akan dipanggil.
// Java double calCircumference(double radius, double pi); double calCircumference(double radius);
Dalam definisi metode Java yang terakhir dihasilkan, parameter pi
dihilangkan. Ini berarti bahwa metode tersebut akan menggunakan nilai pi
default.
Unlimited Arguments
Di Java, kita dapat membuat metode untuk menerima sejumlah argumen yang tidak ditentukan dengan menyertakan elipsis (...
) setelah mengetikkan dalam daftar parameter metodenya. Konsep ini juga didukung oleh function Kotlin dengan penggunaan vararg
modifier yang diikuti dengan nama parameter.
fun printInts(vararg ints: Int): Unit { for (n in ints) { print("$n\t") } } printInts(1, 2, 3, 4, 5, 6) // will print 1 2 3 4 5 6
Vararg
modifier memungkinkan pemanggil untuk masuk dalam daftar argumen yang dipisahkan koma. Di balik layar, daftar argumen ini akan dibungkus dalam sebuah array.
Bila sebuah function memiliki beberapa parameter, parameter vararg
biasanya adalah yang terakhir. Hal ini juga memungkinkan untuk memiliki parameter setelah vararg
, namun Anda harus menggunakan named parameter untuk menentukannya saat Anda memanggil function.
fun printNumbers(myDouble: Double, myFloat: Float, vararg ints: Int) { println(myDouble) println(myFloat) for (n in ints) { print("$n\t") } } printNumbers(1.34, 4.4F, 2, 3, 4, 5, 6) // will compile
Misalnya, pada kode di atas, parameter dengan vararg
modifier berada pada posisi terakhir dalam daftar beberapa parameter (inilah yang biasanya kita lakukan). Tapi bagaimana kalau kita tidak menginginkannya di posisi terakhir? Pada contoh berikut, berada di posisi kedua.
fun printNumbers(myDouble: Double, vararg ints: Int, myFloat: Float) { println(myDouble) println(myFloat) for (n in ints) { print("$n\t") } } printNumbers(1.34, 2, 3, 4, 5, 6, myFloat = 4.4F) // will compile printNumbers(1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // will not compile printNumbers(myDouble = 1.34, ints = 2, 3, 4, 5, 6, myFloat = 4.4F) // will also not compile
Seperti yang dapat Anda amati dalam kode yang diperbarui di atas, kami menggunakan named argumen pada parameter terakhir untuk menyelesaikan ini.
Spread Operator
Misalkan kita ingin melewati array bilangan bulat ke function printNumbers()
. Function ini mengharapkan nilai yang akan dibuka kembali ke dalam daftar parameter. Jika Anda mencoba untuk melewatkan array langsung ke printNumbers()
, Anda akan melihat bahwa itu tidak akan di-compile.
val intsArray: IntArray = intArrayOf(1, 3, 4, 5) printNumbers(1.34, intsArray, myFloat = 4.4F) // won't compile
Untuk mengatasi masalah ini, kita perlu menggunakan operator penyebaran *
. Operator ini akan membongkar array dan kemudian melewati elemen individual sebagai argumen ke function untuk kita.
val intsArray: IntArray = intArrayOf(1, 3, 4, 5) printNumbers(1.34, *intsArray, myFloat = 4.4F) // will now compile
Dengan memasukkan operator penyebaran *
di depan intsArray
dalam daftar argumen function, kode sekarang dapat di-compile dan menghasilkan hasil yang sama seperti jika kita telah melewati elemen intsArray
sebagai daftar argumen yang dipisahkan koma.
Return Multiple Values
Terkadang kita ingin mengembalikan beberapa nilai dari suatu function. Salah satu cara adalah dengan menggunakan tipe Pair
di Kotlin untuk membuat Pair
dan kemudian mengembalikannya. Struktur Pair
ini membungkus dua nilai yang nantinya bisa diakses. Tipe Kotlin ini bisa menerima tipe yang Anda berikan pada konstruktornya. Dan, terlebih lagi, kedua tipe ini bahkan tidak perlu sama.
fun getUserNameAndState(id: Int): Pair<String?, String?> { require(id > 0, { "Error: id is less than 0" }) val userNames: Map<Int, String> = mapOf(101 to "Chike", 102 to "Segun", 104 to "Jane") val userStates: Map<Int, String> = mapOf(101 to "Lagos", 102 to "Imo", 104 to "Enugu") val userName = userNames[id] val userState = userStates[id] return Pair(userName, userState) }
Pada function di atas, kami membuat Pair
baru dengan melewatkan variabel userName
dan userState
sebagai argumen pertama dan kedua masing-masing ke konstruktornya, dan kemudian mengembalikan Pair
ini ke pemanggil.
Hal lain yang perlu diperhatikan adalah kita menggunakan function yang disebut require()
pada function getUserNameAndState()
. Fungsi penolong ini dari library standar yang digunakan untuk memberi function kepada pemanggil sebuah prasyarat untuk terpenuhi, atau IllegalArgumentException
akan dilemparkan (kita akan membahas Exceptions di Kotlin di artikel selanjutnya). Argumen kedua opsional untuk require()
adalah function literal yang mengembalikan pesan yang akan ditampilkan jika Exceptions dilempar. Misalnya, memanggil function getUserNameAndState()
dan melewati -1
sebagai argumen untuk itu akan memicu:



Retrieving Data From Pair
val userNameAndStatePair: Pair<String?, String?> = getUserNameAndState(101) println(userNameAndStatePair.first) // Chike println(userNameAndStatePair.second) // Lagos
Pada kode di atas, kita mengakses nilai first dan second dari tipe Pair
dengan menggunakan properti first
dan second
.
Namun, ada cara yang lebih baik untuk melakukan hal ini: destrukturisasi.
val (name, state) = getUserNameAndState(101) println(name) // Chike println(state) // Lagos
Apa yang telah kita lakukan dalam kode yang diperbarui di atas adalah dengan langsung menetapkan nilai pertama dan kedua dari tipe Pair
yang dikembalikan ke name
variabel dan state
masing-masing. Fitur ini disebut deklarasi destrukturisasi.
Triple Return Values dan Luar
Nah, bagaimana jika Anda ingin mengembalikan tiga nilai sekaligus? Kotlin menyediakan tipe lain yang berguna yang disebut Triple
.
fun getUserNameStateAndAge(id: Int): Triple<String?, String?, Int> { require(id > 0, { "id is less than 0" }) val userNames: Map<Int, String> = mapOf(101 to "Chike", 102 to "Segun", 104 to "Jane") val userStates: Map<Int, String> = mapOf(101 to "Lagos", 102 to "Imo", 104 to "Enugu") val userName = userNames[id] val userState = userStates[id] val userAge = 6 return Triple(userNames[id], userStates[id], userAge) } val (name, state, age) = getUserNameStateAndAge(101) println(name) // Chike println(state) // Lagos println(age) // 6
Saya yakin beberapa dari Anda bertanya-tanya apa yang harus dilakukan jika Anda ingin mengembalikan lebih dari tiga nilai. Jawaban untuk itu akan di posting selanjutnya, saat kita membahas class data di Kotlin.
Kesimpulan
Dalam tutorial ini, Anda belajar tentang package dan function dasar dalam bahasa pemrograman Kotlin. Dalam tutorial berikutnya di seri Kotlin From Scratch, Anda akan belajar lebih banyak tentang function di Kotlin. Sampai jumpa lagi!
Untuk mempelajari lebih lanjut tentang bahasa Kotlin, saya sarankan untuk mengunjungi dokumentasi Kotlin. Atau lihat beberapa postingan pengembangan aplikasi Android kami yang lain di Envato Tuts+!
- Android SDKPengenalan Komponen Arsitektur AndroidTin Megali
- Machine LearningMembuat Chat-bot pada Android dengan IBM WatsonAshraff Hathibelagal
- Android SDKJawa vs Kotlin: Anda harus menggunakan Kotlin untuk Membangun Android?Jessica Thornsby
- Android SDKTips Singkat: Menulis kode yang bersih dengan Kotlin SAM-ConversionsAshraff Hathibelagal
- Android SDKAndroid O: Verifikasi Nomor Telepon Dengan Token SMSChike Mgbemena