Saat menjalankan program Kotlin dari terminal, kita dapat menyertakan argumen setelah nama file atau nama program. Argumen-argumen ini diteruskan oleh runtime ke function main sebagai array bertipe Array<String>. Mekanisme ini memungkinkan kita membangun program CLI yang fleksibel — misalnya kotlin app.kt --port 8080 --host 0.0.0.0 — tanpa harus meminta input interaktif. Pada chapter ini kita akan membongkar signature main yang menerima args, cara mengiterasi argumen, dan pola getOrElse/getOrNull untuk akses yang aman terhadap indeks di luar batas.

Signature main dengan args #

Terdapat dua bentuk main yang dapat kita gunakan di Kotlin:

kotlin Contoh: dua bentuk main
// Bentuk tanpa argumen (Kotlin 1.3+)
fun main() {
    println("Tanpa argumen")
}

// Bentuk dengan argumen baris perintah
fun main(args: Array<String>) {
    println("Menerima ${args.size} argumen")
}

Kedua bentuk tersebut sama-sama valid sebagai titik masuk program. Bentuk pertama cocok untuk program interaktif yang hanya membaca stdin. Bentuk kedua wajib dipakai ketika program perlu membaca argumen baris perintah dari pengguna. Tipe elemen Array<String> — bukan IntArray atau List<String> — karena argumen baris perintah selalu berupa teks.

Mengakses dan Mengiterasi args #

kotlin
fun main(args: Array<String>) {
    println("Jumlah argumen: ${args.size}")

    println("--- Iterasi dengan index ---")
    for (i in args.indices) {
        println("args[$i] = ${args[i]}")
    }

    println("--- Iterasi for-each ---")
    for (arg in args) {
        println("arg: $arg")
    }

    println("--- args.getOrElse ---")
    val host = args.getOrElse(0) { "localhost" }
    val port = args.getOrElse(1) { "8080" }
    println("host=$host, port=$port")

    println("--- args.getOrNull ---")
    val env = args.getOrNull(2)
    println("env=$env")

    println("--- Filter flags ---")
    val flags = args.filter { it.startsWith("--") }
    println("Flags: $flags")
}

Output yang Dihasilkan:

text
Jumlah argumen: 5
--- Iterasi dengan index ---
args[0] = --port
args[1] = 8080
args[2] = --host
args[3] = 0.0.0.0
args[4] = --verbose
--- Iterasi for-each ---
arg: --port
arg: 8080
arg: --host
arg: 0.0.0.0
arg: --verbose
--- args.getOrElse ---
host=--port, port=8080
--- args.getOrNull ---
env=--host
--- Filter flags ---
Flags: [--port, --host, --verbose]

Mari kita telaah baris-baris kode di atas:

  1. Baris 1 (fun main(args: Array<String>)): signature main menerima parameter args bertipe Array<String>. Runtime JVM akan mem-parse argumen baris perintah (dipisah spasi) menjadi elemen-elemen array ini. Tanda kutip ganda dapat dipakai di shell untuk mengelompokkan kata yang mengandung spasi.
  2. Baris 2 (args.size): properti size dari Array mengembalikan jumlah argumen yang diberikan. Jika program dijalankan tanpa argumen, args.size bernilai 0 dan args adalah array kosong — bukan null.
  3. Baris 5–7 (for (i in args.indices)): args.indices adalah IntRange dari 0 hingga args.size - 1. Kita dapat mengakses elemen dengan args[i], mirip dengan akses array di Java.
  4. Baris 10–12 (for (arg in args)): bentuk iterasi for-each yang lebih ringkas. Variabel arg otomatis bertipe String karena args adalah Array<String>.
  5. Baris 15 (args.getOrElse(0) { "localhost" }): extension function getOrElse mengembalikan elemen pada indeks 0 jika ada. Jika indeks di luar batas, lambda { "localhost" } dievaluasi dan hasilnya dikembalikan. Ini adalah cara idiomatis untuk memberikan nilai default.
  6. Baris 20 (args.getOrNull(2)): mirip getOrElse, tetapi mengembalikan null ketika indeks di luar batas. Cocok jika kita ingin membedakan “tidak ada argumen” dari “argumen kosong”.
  7. Baris 25 (args.filter { it.startsWith("--") }): ekstensi filter pada Array mengembalikan List<String> berisi elemen yang memenuhi predikat. Ekspresi it merujuk ke elemen yang sedang diperiksa.

Menjalankan Program dengan Argumen #

Saat kompilasi mandiri menggunakan kotlinc, kita menjalankan file .kt langsung dengan perintah kotlin. Argumen setelah nama file akan diteruskan ke args:

bash Contoh: menjalankan program Kotlin dengan argumen
# Kompilasi ke JAR yang dapat dieksekusi
kotlinc app.kt -include-runtime -d app.jar

# Jalankan dengan argumen
java -jar app.jar --port 8080 --host 0.0.0.0

# Atau gunakan kotlin script (tanpa kompilasi eksplisit)
kotlin app.kt --port 8080

Saat dijalankan di terminal, shell memecah argumen berdasarkan spasi. Tanda kutip dapat dipakai untuk mengelompokkan kata yang mengandung spasi menjadi satu argumen:

bash Contoh: argumen dengan spasi
java -jar app.jar --nama "Budi Santoso" --kota "Yogyakarta"
# args[0] = --nama
# args[1] = Budi Santoso
# args[2] = --kota
# args[3] = Yogyakarta

Pola Parsing Flag Sederhana #

Untuk CLI yang menerima flag berpasangan seperti --port 8080, kita dapat membangun parser sederhana dengan iterasi manual:

kotlin Contoh: parser flag sederhana
fun main(args: Array<String>) {
    var port = 8080
    var host = "localhost"
    var verbose = false

    var i = 0
    while (i < args.size) {
        when (args[i]) {
            "--port" -> {
                port = args.getOrElse(i + 1) { "8080" }.toInt()
                i += 2
            }
            "--host" -> {
                host = args.getOrElse(i + 1) { "localhost" }
                i += 2
            }
            "--verbose" -> {
                verbose = true
                i += 1
            }
            else -> {
                println("Argumen tidak dikenal: ${args[i]}")
                i += 1
            }
        }
    }

    println("host=$host, port=$port, verbose=$verbose")
}

Pola di atas menampilkan manual parsing yang umum dijumpai di program CLI sederhana. Untuk proyek produksi, pertimbangkan library seperti kotlinx-cli atau picocli yang menyediakan parser argumen deklaratif beserta generation otomatis dari help text.

Validasi Argumen Wajib #

Untuk argumen yang wajib ada, kombinasikan getOrElse dengan require:

kotlin Contoh: validasi argumen wajib
fun main(args: Array<String>) {
    val namaFile = args.getOrElse(0) {
        println("Penggunaan: program <nama-file> [--verbose]")
        return
    }
    println("Memproses file: $namaFile")
}

Function return di dalam lambda getOrElse akan menghentikan main lebih awal — pola yang lazim disebut early return. Tanpa argumen pertama, program mencetak pesan penggunaan dan keluar tanpa melanjutkan pemrosesan.

Referensi Lanjutan #

Setelah memahami cara membaca argumen baris perintah, kita siap beranjak ke topik yang menjadi inti hampir setiap output Kotlin: string template dengan tanda $.