File .kts adalah wujud nyata Kotlin Scripting yang paling sering dipakai. Berbeda dari file .kt biasa yang wajib memiliki fun main() di dalam sebuah class, file .kts menerima pernyataan top-level langsung tanpa pembungkus. Hal ini membuat skrip terasa ringkas seperti Python atau Bash, namun tetap memiliki type-safety penuh Kotlin. Pada bab ini kita akan membedah empat unsur anatomi file .kts: pernyataan top-level, akses args, function lokal, dan shebang untuk pemanggilan langsung.
Top-Level Statement #
Bagian terbesar file .kts berisi pernyataan top-level: deklarasi variabel, pemanggilan function, dan kontrol alur. Saat kompilator memproses skrip, semua pernyataan ini dikumpulkan menjadi body sebuah class generated yang memiliki entry point khusus.
val nama = "Budi"
val tahun = 2026
println("Halo, $nama! Tahun $tahun.")Tidak ada fun main(), tidak ada class, dan tidak ada package deklarasi. Tiga baris tersebut sudah cukup untuk dijalankan dengan kotlinc -script halo.kts.
Akses args dari Command Line #
File .kts dapat menerima argumen dari command line lewat variabel khusus args. Variabel ini tersedia otomatis di seluruh skrip dan bertipe Array<String>. Perhatikan contoh skrip berikut yang menyapa pengguna berdasarkan argumen pertama.
// Pemakaian: kotlinc -script sapa.kts Budi 2026
when (args.size) {
0 -> println("Penggunaan: sapa.kts <nama> <tahun>")
1 -> println("Halo, ${args[0]}!")
else -> {
val nama = args[0]
val tahun = args[1].toIntOrNull() ?: 2026
println("Halo, $nama! Tahun $tahun.")
}
}Array args diindeks dari 0. Selalu validasi args.size sebelum mengakses indeks tertentu untuk menghindari ArrayIndexOutOfBoundsException.
Simulasi Anatomi Skrip #
Karena file .kts tidak dapat dikompilasi langsung dengan kotlinc biasa (memerlukan kotlinc -script), cuplikan berikut mensimulasikan struktur skrip sebagai file .kt standar yang merefleksikan anatomi sebenarnya:
// Demo anatomi file .kts: top-level statements, args, dan shebang.
// File .kt ini mensimulasikan apa yang dijalankan kompilator saat
// membaca file .kts dengan parameter argumen.
import kotlin.math.PI
import kotlin.math.roundToInt
fun main(args: Array<String>) {
println("=== Anatomi File .kts ===")
println()
// Bagian 1: pernyataan top-level tanpa pembungkus class/function.
val pesan = "Halo dari skrip Kotlin"
val pengguna = "Budi"
println("Bagian 1 — Top-level statement:")
println(" pesan = $pesan")
println(" pengguna = $pengguna")
println()
// Bagian 2: akses args dari command line.
// Saat menjalankan .kts dengan `kotlinc -script halo.kts Budi 2026`,
// argumen "Budi" dan "2026" tersedia dalam array args.
println("Bagian 2 — Akses args (command-line argument):")
if (args.isEmpty()) {
println(" Tidak ada argumen. Jalankan: kotlinc -script halo.kts Budi 2026")
println(" Memakai nilai default: pengguna=Budi, tahun=2026")
} else {
println(" Jumlah argumen: ${args.size}")
args.forEachIndexed { i, a ->
println(" args[$i] = $a")
}
}
println()
// Bagian 3: definisi function lokal tetap didukung di .kts.
fun sapa(nama: String, tahun: Int): String =
"Halo, $nama! Selamat datang di tahun $tahun."
println("Bagian 3 — Function lokal:")
println(" ${sapa("Siti", 2026)}")
println()
// Bagian 4: import dan standard library tetap berfungsi.
val piBulat = (PI * 100).roundToInt() / 100.0
println("Bagian 4 — Standard library:")
println(" PI dibulatkan 2 desimal = $piBulat")
}Output yang Dihasilkan:
=== Anatomi File .kts ===
Bagian 1 — Top-level statement:
pesan = Halo dari skrip Kotlin
pengguna = Budi
Bagian 2 — Akses args (command-line argument):
Tidak ada argumen. Jalankan: kotlinc -script halo.kts Budi 2026
Memakai nilai default: pengguna=Budi, tahun=2026
Bagian 3 — Function lokal:
Halo, Siti! Selamat datang di tahun 2026.
Bagian 4 — Standard library:
PI dibulatkan 2 desimal = 3.14Mari kita amati setiap bagian dari kode di atas:
- Bagian 1 (top-level statement): variabel
pesandanpenggunadideklarasikan langsung di bodymain(). Pada file.ktsasli, baris-baris ini akan berada di root file tanpa pembungkus function. - Bagian 2 (akses args): blok
if (args.isEmpty())memvalidasi argumen sebelum dipakai. Validasi ini wajib karena skrip bisa dipanggil tanpa argumen sama sekali. - Bagian 3 (function lokal): function
sapadideklarasikan di dalam bodymain(). Pada file.kts, function top-level tetap didukung dan dapat ditempatkan di mana saja sebelum pemanggilan. - Bagian 4 (standard library):
kotlin.math.PIdanroundToInt()diimpor di awal file. Import harus selalu berada di bagian atas file.kts, sama seperti file.ktbiasa.
Shebang untuk Pemanggilan Langsung #
Sistem operasi Unix mendukung shebang #! di baris pertama file untuk menentukan interpreter. File .kts dapat memakai shebang #!/usr/bin/env kotlinc -script sehingga dapat dipanggil langsung tanpa mengetik kotlinc -script di depan.
#!/usr/bin/env kotlinc -script
println("Skrip dipanggil langsung")
println("Argument count: ${args.size}")Setelah file disimpan (misalnya halo.kts), beri permission eksekusi dan panggil langsung:
chmod +x halo.kts
./halo.kts Budi 2026Shebang baris pertama akan diabaikan oleh kompilator Kotlin sebagai komentar, namun dikenali oleh kernel untuk memanggil interpreter yang tepat.
Function Lokal dan Helper #
Skrip tidak terbatas pada pernyataan sekuensial. Kita dapat mendefinisikan function helper, extension function, dan bahkan class data di dalam file .kts. Function top-level harus dideklarasikan sebelum dipanggil (Kotlin Scripting tidak melakukan hoisting seperti JavaScript).
fun hitungPajak(harga: Double, tarif: Double = 0.11): Double = harga * tarif
val daftar = listOf(
"Buku" to 50000.0,
"Pulpen" to 12000.0,
"Tas" to 150000.0
)
daftar.forEach { (nama, harga) ->
val pajak = hitungPajak(harga)
println("$nama: harga=$harga, pajak=$pajak")
}Function hitungPajak dideklarasikan lebih dulu, lalu dipakai di forEach. Bila urutan dibalik, kompilator akan melaporkan unresolved reference.
Referensi Lanjutan #
- Kotlin Scripting
— panduan resmi Kotlin untuk anatomi file
.ktsdan top-level statement - kotlin-main-kts
— contoh skrip
main-ktsdi GitHub untuk pemakaian shebang dan dependensi
Selanjutnya #
Anatomi .kts sudah jelas. Selanjutnya kita akan naik ke level lebih praktis: membangun CLI tool utuh dengan struktur command, sub-command, dan exit code. Materi tersebut ada di chapter Command-Line Utilities.