Menyusun teks panjang dengan banyak baris menggunakan string biasa cepat menjadi tidak terbaca: setiap baris baru harus ditulis \n, setiap tanda kutip harus di-escape dengan \", dan struktur kode menjadi sulit dipetakan secara visual. Kotlin mengadopsi fitur raw string dari Groovy: literal yang diapit tiga tanda kutip ganda """...""" menyimpan baris baru apa adanya dan tidak memproses escape sequence. Pada chapter ini kita akan mempelajari perilaku raw string, kapan escape tetap diproses dan kapan tidak, serta bagaimana menyisipkan karakter $ literal. Pemahaman ini menjadi pintu menuju teknik trimIndent dan trimMargin pada chapter berikutnya.

Sintaks Dasar Raw String #

Sebuah raw string dimulai dengan """ dan diakhiri dengan """. Karakter baris baru di dalam literal dipertahankan apa adanya, demikian juga spasi dan tab. Tanda kutip tunggal " di dalamnya tidak perlu di-escape, yang sangat memudahkan penyusunan JSON atau HTML.

kotlin Contoh: raw string sederhana
val teks = """
    Baris pertama
    Baris kedua
    Baris ketiga
"""

Perhatikan bahwa baris baru setelah """ dan sebelum """ juga menjadi bagian dari string. Hal ini sering menjadi sumber kebingungan karena baris pertama dan terakhir biasanya kosong. Karena itu kita hampir selalu menggabungkan raw string dengan trimIndent() atau trimMargin(), yang akan kita bahas pada chapter khusus.

Karakter Escape Tidak Diproses #

Berbeda dengan string biasa yang memproses \n, \t, \\, dan \", raw string menyimpan karakter backslash apa adanya. Penulisan \t dalam raw string akan menghasilkan dua karakter: backslash dan huruf t.

kotlin Contoh: escape tidak diproses
val a = "baris1\nbaris2"     // string biasa, \n menjadi newline
val b = """baris1\nbaris2""" // raw string, \n tetap sebagai dua karakter
println(a.length)            // 13
println(b.length)            // 14

Hal ini berguna saat kita menulis teks yang mengandung banyak backslash, misalnya ekspresi reguler atau path Windows C:\Users\Budi. Karena escape tidak diproses, kita tidak perlu menulis \\ untuk mendapatkan satu backslash.

Karakter $ dan Template #

Raw string tetap memproses string template $var dan ${expr}. Untuk menyisipkan karakter $ literal (bukan sebagai penanda template), gunakan ${'$'} karena \$ tidak dikenali di raw string:

kotlin Contoh: $ literal di raw string
val harga = 500
val teks = """
    Harga: ${'$'}$harga
    Kurs: ${'$'}1 = Rp15.000
""".trimIndent()
println(teks)

Baris Harga: ${'$'}$harga akan menghasilkan Harga: $500 — ${'$'} menyisipkan karakter $ literal, lalu $harga dievaluasi sebagai template.

Kegunaan Umum: JSON, SQL, HTML #

Raw string cocok untuk teks terstruktur dengan banyak tanda kutip dan baris baru. Tiga kegunaan paling umum adalah:

kotlin
fun main() {
    val sql = """
        SELECT id, nama, email
        FROM pengguna
        WHERE aktif = true
        ORDER BY nama ASC
    """.trimIndent()
    println("Query SQL:")
    println(sql)
    println("---")

    val json = """
        {
          "nama": "Budi",
          "umur": 30,
          "aktif": true,
          "hobi": ["membaca", "bersepeda"]
        }
    """.trimIndent()
    println("JSON:")
    println(json)
    println("---")

    val pesan = """
        |Halo pelanggan,
        |Terima kasih telah berlangganan.
        |Salam hangat,
        |Tim Layanan
    """.trimMargin()
    println("Surat:")
    println(pesan)
    println("---")

    val teks = "baris satu\nbaris dua\nbaris tiga"
    println("Cetak langsung teks dengan \\n:")
    println(teks)
    println("---")

    val raw = """\t\ttidak ter-escape"""
    println("Raw string: $raw")

    val denganDolar = """
        Harga: ${'$'}500
        Kurs: ${'$'}1 = Rp15.000
    """.trimIndent()
    println(denganDolar)
    println("---")

    val html = """
        <html>
          <body>
            <h1>Halo Kotlin</h1>
          </body>
        </html>
    """.trimIndent()
    println("HTML:")
    println(html)
}

Output yang Dihasilkan:

text
Query SQL:
SELECT id, nama, email
FROM pengguna
WHERE aktif = true
ORDER BY nama ASC
---
JSON:
{
  "nama": "Budi",
  "umur": 30,
  "aktif": true,
  "hobi": ["membaca", "bersepeda"]
}
---
Surat:
Halo pelanggan,
Terima kasih telah berlangganan.
Salam hangat,
Tim Layanan
---
Cetak langsung teks dengan \n:
baris satu
baris dua
baris tiga
---
Raw string: \t\ttidak ter-escape
Harga: $500
Kurs: $1 = Rp15.000
---
HTML:
<html>
  <body>
    <h1>Halo Kotlin</h1>
  </body>
</html>

Mari kita telaah bagian penting dari kode di atas. Blok sql memperlihatkan bahwa baris baru di dalam raw string dipertahankan apa adanya — kompilator tidak memproses \n karena tidak ada di sini, melainkan baris baru literal di sumber. Blok json menunjukkan tanda kutip ganda " tidak perlu di-escape, sehingga struktur JSON tetap mudah dibaca. Blok pesan menggunakan trimMargin("|") untuk menghapus prefix | dan indentasi di sekitarnya — teknik yang akan kita bedah pada chapter berikutnya. Baris val raw = """\t\ttidak ter-escape""" membuktikan bahwa escape \t tetap menjadi dua karakter (backslash dan t) di output. Terakhir, blok denganDolar menunjukkan trik ${'$'} untuk menyisipkan tanda dolar literal.

Perbandingan dengan String Biasa #

AspekString biasa "..."Raw string """..."""
Baris baruHanya via \nLangsung dari sumber
Tanda kutip "Harus di-escape \"Tidak perlu di-escape
Escape \n, \tDiprosesTidak diproses
Template $varDidukungDidukung
Karakter $ literal\$${'$'}
Cocok untuk teks satu barisYaTidak

Pilih tipe literal berdasarkan kebutuhan: string biasa untuk teks pendek dengan escape, raw string untuk teks panjang multi-baris dengan struktur.

Referensi Lanjutan #

  • Strings — bagian multiline string literal """...""" pada panduan resmi

Penutup #

Raw string memecahkan masalah penulisan teks panjang, tetapi meninggalkan masalah baru: indentasi dari kode sumber ikut tersimpan dalam string. Untuk membersihkan indentasi yang tidak diinginkan tanpa mengganggu indentasi internal yang sengaja dibuat, Kotlin menyediakan trimIndent() dan trimMargin() — topik yang akan kita bahas tuntas pada chapter Trimming Indent dan Margin.