A.48. Arguments & Flag
Arguments adalah data argument opsional yang disisipkan ketika eksekusi program. Sedangkan flag merupakan ekstensi dari argument. Dengan flag, penulisan argument menjadi lebih rapi dan terstruktur.
Pada chapter ini kita akan belajar tentang penerapan arguments dan flag.
A.48.1. Penggunaan Arguments
Data arguments bisa didapat lewat variabel os.Args (package os perlu di-import terlebih dahulu). Data tersebut tersimpan dalam bentuk array. Setiap data argument yang disisipkan saat pemanggilan program, datanya dipecah menggunakan karakter spasi lalu di-map ke bentuk array. Contoh penerapan:
package main
import "fmt"
import "os"
func main() {
var argsRaw = os.Args
fmt.Printf("-> %#v\n", argsRaw)
// -> []string{".../bab45", "banana", "potato", "ice cream"}
var args = argsRaw[1:]
fmt.Printf("-> %#v\n", args)
// -> []string{"banana", "potato", "ice cream"}
}
Argument disisipkan saat eksekusi program. Sebagai contoh, kita ingin menyisipkan 3 buah argumen berikut: banana, potato, dan ice cream. Maka penulisan saat pemanggilan program-nya seperti ini:
Menggunakan
go rungo run bab45.go banana potato "ice cream"Menggunakan
go buildgo build bab45.go $ ./bab45 banana potato "ice cream"
Output program:

Bisa dilihat pada kode di atas, bahwa untuk data argumen yang ada karakter spasi-nya ( ) harus dituliskan dengan diapit tanda petik (") agar tidak dideteksi sebagai 2 argumen.
Variabel os.Args berisi tak hanya arguments saja, tapi juga path file executable pada index ke-0 (jika eksekusi-nya menggunakan go run maka path akan merujuk ke folder temporary). Maka di sini penting untuk hanya mengambil elemen index ke-1 dan seterusnya saja via statement os.Args[1:].
A.48.2. Penggunaan Flag
Flag memiliki kegunaan yang sama seperti arguments, yaitu untuk parameterize eksekusi program, dengan penulisan dalam bentuk key-value. Berikut merupakan contoh penerapannya.
package main
import "flag"
import "fmt"
func main() {
var name = flag.String("name", "anonymous", "type your name")
var age = flag.Int64("age", 25, "type your age")
flag.Parse()
fmt.Printf("name\t: %s\n", *name)
fmt.Printf("age\t: %d\n", *age)
}
Cara penulisan arguments menggunakan flag:
go run bab45.go -name="john wick" -age=28
Tiap argument harus ditentukan key, tipe data, dan nilai default-nya. Contohnya seperti pada flag.String() di atas. Agar lebih mudah dipahami, mari kita bahas kode berikut.
var dataName = flag.String("name", "anonymous", "type your name")
fmt.Println(*dataName)
Kode tersebut maksudnya adalah, disiapkan flag bertipe string, dengan key adalah name, dengan nilai default "anonymous", dan keterangan "type your name". Nilai flag nya sendiri akan disimpan ke dalam variabel dataName.
Nilai balik fungsi flag.String() adalah string pointer, jadi perlu di-dereference terlebih dahulu untuk mengakses nilai aslinya (*dataName).

Flag yang nilainya tidak diset, secara otomatis akan mengembalikan nilai default.
Tabel berikut merupakan macam-macam fungsi flag yang tersedia untuk tiap jenis tipe data.
| Nama Fungsi | Return Value |
|---|---|
flag.Bool(name, defaultValue, usage) |
*bool |
flag.Duration(name, defaultValue, usage) |
*time.Duration |
flag.Float64(name, defaultValue, usage) |
*float64 |
flag.Int(name, defaultValue, usage) |
*int |
flag.Int64(name, defaultValue, usage) |
*int64 |
flag.String(name, defaultValue, usage) |
*string |
flag.Uint(name, defaultValue, usage) |
*uint |
flag.Uint64(name, defaultValue, usage) |
*uint64 |
A.48.3. Deklarasi Flag Dengan Cara Passing Reference Variabel Penampung Data
Sebenarnya ada 2 cara deklarasi flag yang bisa digunakan, dan cara di atas merupakan cara pertama.
Cara kedua mirip dengan cara pertama, perbedaannya: pada cara pertama nilai pointer flag dikembalikan lalu ditampung variabel, sedangkan pada cara kedua nilainya di-set lewat parameter pointer.
Agar lebih jelas perhatikan contoh berikut:
// cara ke-1
var data1 = flag.String("name", "anonymous", "type your name")
fmt.Println(*data1)
// cara ke-2
var data2 string
flag.StringVar(&data2, "gender", "male", "type your gender")
flag.Parse()
fmt.Println(data2)
Tinggal tambahkan akhiran Var pada pemanggilan nama fungsi flag yang digunakan (contoh flag.IntVar(), flag.BoolVar(), dll), lalu disisipkan referensi variabel penampung flag sebagai parameter pertama.
Kegunaan dari parameter terakhir method-method flag adalah untuk memunculkan hints atau petunjuk arguments apa saja yang bisa dipakai, ketika argument --help ditambahkan saat eksekusi program.

A.48.4. Fungsi flag.TextVar() (Go 1.21+)
Sejak Go 1.21, tersedia fungsi flag.TextVar() untuk mendaftarkan flag dengan tipe data kustom yang mengimplementasikan interface encoding.TextUnmarshaler. Ini berguna untuk tipe-tipe seperti time.Time, net.IP, atau tipe buatan sendiri yang bisa diparsing dari teks.
package main
import (
"flag"
"fmt"
"net"
)
func main() {
var ip net.IP
flag.TextVar(&ip, "ip", net.IPv4(127, 0, 0, 1), "IP address")
flag.Parse()
fmt.Println("ip:", ip)
}
Jalankan dengan:
go run main.go -ip=192.168.1.1
Output:
ip: 192.168.1.1
flag.TextVar() memanggil method UnmarshalText() dari tipe yang diberikan untuk mengkonversi nilai string dari argument menjadi tipe yang sesuai.