Program nyata menerima angka dalam wujud teks: argumen command line berupa "42", harga dari berkas konfigurasi, atau umur dari form pendaftaran. Sebaliknya, program juga perlu mengirim angka keluar sebagai teks yang bisa dibaca manusia. Package strconv (string conversion) adalah jembatan dua arah antara angka dan string di Go. Ciri khasnya: setiap operasi baca dari teks mengembalikan nilai balik tambahan bertipe error, sehingga input salah tertangkap sebagai data, bukan panic.

Atoi dan Itoa #

Fungsi strconv.Atoi (ASCII to integer) mengubah teks basis sepuluh menjadi int, sedangkan strconv.Itoa melakukan sebaliknya. Hasil Atoi berupa pasangan nilai dan error:

go
n, _ := strconv.Atoi("42")
fmt.Println(n + 8, strconv.Itoa(n))

Output yang Dihasilkan:

text
50 42

Konversi ke angka baru memungkinkan operasi aritmetika — n + 8 menghasilkan 50, hal yang mustahil dilakukan pada teks "42". Fungsi Itoa tidak pernah gagal karena setiap nilai int selalu punya representasi teks. Kebutuhan yang lebih umum dilayani oleh strconv.ParseInt(teks, basis, bitSize) — Atoi("2026") ekuivalen dengan ParseInt("2026", 10, 0) — dan strconv.ParseUint untuk bilangan positif.

Menangkap Error Konversi #

Input pengguna tidak selalu berupa angka bersih. Pemanggilan strconv.Atoi("2026abc") pada program utuh di bawah menghasilkan pesan asli:

text
strconv.Atoi: parsing "2026abc": invalid syntax

Error tersebut bertipe *strconv.NumError — sebuah struct dengan tiga field: Func berisi nama fungsi yang gagal (Atoi), Num berisi teks masukan (2026abc), dan Err berisi penyebab dasarnya. Penyebab ada dua macam: strconv.ErrSyntax untuk teks yang bukan angka sama sekali, dan strconv.ErrRange untuk angka yang benar tetapi melampaui kapasitas tipe — misalnya Atoi("99999999999999999999") menghasilkan error value out of range. Karena *strconv.NumError mengimplementasikan Unwrap, pemeriksaan penyebab cukup memakai errors.Is(err, strconv.ErrSyntax).

ParseFloat dan FormatFloat #

Angka desimal ditangani strconv.ParseFloat("3.5", 64) — argumen kedua adalah bitSize (32 atau 64) yang menentukan presisi hasil. Seperti Atoi, ParseFloat juga mengembalikan error untuk teks yang bukan angka; pada program utuh, masukannya teks pasti-valid sehingga error sengaja dilewati dengan _. Pencerminannya ada dua: strconv.FormatFloat(f, 'f', 1, 64) menulis float64 dengan format desimal dan satu digit di belakang koma, sedangkan strconv.FormatInt(255, 16) menulis bilangan bulat pada basis 16, menghasilkan "ff". Format 'f' menghasilkan notasi biasa, 'e' notasi ilmiah, dan 'g' memilih yang paling ringkas — ketiganya diatur argumen kedua FormatFloat.

Quote dan Unquote #

Fungsi strconv.Quote mengubah string arbitrary menjadi literal Go yang aman dibaca: karakter kontrol menjadi escape \n, tanda kutip menjadi \". Fungsi strconv.Unquote membalik proses tersebut dengan memparsing literal yang diawali dan diakhiri kutip ganda. Pasangan ini berguna untuk log dan data yang akan dibaca kembali oleh program lain.

ParseBool #

Teks boolean datang dalam banyak wujud: true, TRUE, 1, t. Fungsi strconv.ParseBool menerima "1", "t", "T", "true", "TRUE", "True", "0", "f", "F", "false", "FALSE", "False" — dan menolak sisanya. Pada program utuh, teks "ya" dari konfigurasi menghasilkan pesan strconv.ParseBool: parsing "ya": invalid syntax yang tertangkap rapi tanpa menghentikan program.

Program Utuh #

Berkas strconv-demo.go merangkum seluruh konversi di atas termasuk penangkapan error:

go
package main

import (
	"errors"
	"fmt"
	"strconv"
)

func main() {
	// Atoi: teks menjadi int, error selalu diperiksa.
	n, err := strconv.Atoi("2026")
	if err != nil {
		fmt.Println("galat:", err)
		return
	}
	fmt.Println("Atoi       :", n, "tahun")

	// Itoa: int menjadi teks.
	fmt.Println("Itoa       :", strconv.Itoa(2026))

	// Input salah menghasilkan error, bukan panic.
	n2, err2 := strconv.Atoi("2026abc")
	if err2 != nil {
		fmt.Println("nilai n2   :", n2, "(nol saat gagal)")
		fmt.Println("galat      :", err2)
	}

	// Error strconv bertipe *strconv.NumError.
	if numErr, ok := err2.(*strconv.NumError); ok {
		fmt.Println("NumError   :", numErr.Func, "pada", strconv.Quote(numErr.Num))
	}

	// Penyebab sintaks salah dapat diperiksa dengan errors.Is.
	if errors.Is(err2, strconv.ErrSyntax) {
		fmt.Println("penyebab   : strconv.ErrSyntax")
	}

	// ParseFloat membaca angka desimal.
	f, _ := strconv.ParseFloat("3.5", 64)
	fmt.Println("ParseFloat :", f)

	// FormatFloat dan FormatInt menulis angka kembali jadi teks.
	fmt.Println("FormatFloat:", strconv.FormatFloat(f, 'f', 1, 64))
	fmt.Println("FormatInt  :", strconv.FormatInt(255, 16))

	// Quote meng-escape teks, Unquote membaliknya.
	fmt.Println("Quote      :", strconv.Quote("Halo,\n\"Budi\""))
	s, _ := strconv.Unquote("\"Halo,\\nBudi\"")
	fmt.Println("Unquote    :", s)

	// ParseBool mengenali beberapa bentuk teks boolean.
	for _, teks := range []string{"true", "FALSE", "1", "ya"} {
		b, err3 := strconv.ParseBool(teks)
		fmt.Printf("ParseBool(%q) = %v", teks, b)
		if err3 != nil {
			fmt.Printf(" (galat: %v)", err3)
		}
		fmt.Println()
	}
}
bash
go run strconv-demo.go

Output yang Dihasilkan:

text
Atoi       : 2026 tahun
Itoa       : 2026
nilai n2   : 0 (nol saat gagal)
galat      : strconv.Atoi: parsing "2026abc": invalid syntax
NumError   : Atoi pada "2026abc"
penyebab   : strconv.ErrSyntax
ParseFloat : 3.5
FormatFloat: 3.5
FormatInt  : ff
Quote      : "Halo,\n\"Budi\""
Unquote    : Halo,
Budi
ParseBool("true") = true
ParseBool("FALSE") = false
ParseBool("1") = true
ParseBool("ya") = false (galat: strconv.ParseBool: parsing "ya": invalid syntax)

Mari kita telaah baris demi baris program di atas:

  1. Baris 11-16 (blok Atoi pertama): konversi sukses ditandai err == nil; nilai 2026 baru dicetak setelah pemeriksaan itu, pola yang wajib diikuti setiap pemanggilan Atoi.
  2. Baris 22-26 (Atoi kedua): teks "2026abc" gagal diparsing; blok if menangkap error dan sekaligus menunjukkan nilai balik n2 adalah 0 saat gagal.
  3. Baris 29-31 (type assertion): error dikonfirmasi bertipe *strconv.NumError lalu field Func dan Num-nya dibaca langsung — bukti error adalah struct biasa yang bisa diinspeksi.
  4. Baris 34-36 (errors.Is): pemeriksaan penyebab strconv.ErrSyntax memakai errors.Is, bekerja karena NumError membuka isi Err lewat Unwrap.
  5. Baris 39-44 (ParseFloat/Format): angka 3.5 dibaca sebagai float64 lalu ditulis kembali dengan satu digit desimal, sementara 255 ditulis ulang sebagai heksadesimal ff.
  6. Baris 47-49 (Quote/Unquote): teks berisi baris baru dan kutip di-escape menjadi literal "Halo,\n\"Budi\"", lalu Unquote mengembalikannya sehingga tercetak dua baris.
  7. Baris 52-59 (ParseBool): empat teks diuji; "ya" ditolak dengan pesan invalid syntax yang tercetak sebagai bagian output, bukan sebagai crash.

Konversi angka kini tertangani pada kedua arah. Bab berikutnya berpindah dari teks yang rapi ke data mentah: potongan []byte yang keluar-masuk buffer berkas dan jaringan, diolah package bytes pada chapter Package bytes .

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

strconv-demo.go

Unduh berkas
go
package main

import (
	"errors"
	"fmt"
	"strconv"
)

func main() {
	// Atoi: teks menjadi int, error selalu diperiksa.
	n, err := strconv.Atoi("2026")
	if err != nil {
		fmt.Println("galat:", err)
		return
	}
	fmt.Println("Atoi       :", n, "tahun")

	// Itoa: int menjadi teks.
	fmt.Println("Itoa       :", strconv.Itoa(2026))

	// Input salah menghasilkan error, bukan panic.
	n2, err2 := strconv.Atoi("2026abc")
	if err2 != nil {
		fmt.Println("nilai n2   :", n2, "(nol saat gagal)")
		fmt.Println("galat      :", err2)
	}

	// Error strconv bertipe *strconv.NumError.
	if numErr, ok := err2.(*strconv.NumError); ok {
		fmt.Println("NumError   :", numErr.Func, "pada", strconv.Quote(numErr.Num))
	}

	// Penyebab sintaks salah dapat diperiksa dengan errors.Is.
	if errors.Is(err2, strconv.ErrSyntax) {
		fmt.Println("penyebab   : strconv.ErrSyntax")
	}

	// ParseFloat membaca angka desimal.
	f, _ := strconv.ParseFloat("3.5", 64)
	fmt.Println("ParseFloat :", f)

	// FormatFloat dan FormatInt menulis angka kembali jadi teks.
	fmt.Println("FormatFloat:", strconv.FormatFloat(f, 'f', 1, 64))
	fmt.Println("FormatInt  :", strconv.FormatInt(255, 16))

	// Quote meng-escape teks, Unquote membaliknya.
	fmt.Println("Quote      :", strconv.Quote("Halo,\n\"Budi\""))
	s, _ := strconv.Unquote("\"Halo,\\nBudi\"")
	fmt.Println("Unquote    :", s)

	// ParseBool mengenali beberapa bentuk teks boolean.
	for _, teks := range []string{"true", "FALSE", "1", "ya"} {
		b, err3 := strconv.ParseBool(teks)
		fmt.Printf("ParseBool(%q) = %v", teks, b)
		if err3 != nil {
			fmt.Printf(" (galat: %v)", err3)
		}
		fmt.Println()
	}
}