Mengembalikan lebih dari satu nilai
Tulis tipe-tipe hasilnya di dalam tanda kurung. Kembalikan nilainya dipisahkan koma, dan terima dengan cara yang sama.
Fungsi bawaan min dan max sudah ada sejak Go 1.21. Pemanggil harus menerima setiap hasil: x := minMax(nums) gagal dikompilasi dengan assignment mismatch: 1 variable but minMax returns 2 values.
Konvensi (value, error)
Alasan paling umum mengembalikan dua nilai adalah untuk melaporkan kegagalan. Menurut konvensi, error berada di posisi terakhir, dan saat error-nya tidak nil, hasil lainnya harus dianggap tidak bermakna.
Output:
port: 8080
error: port "http": strconv.Atoi: parsing "http": invalid syntax
error: port out of range
Saat gagal, kembalikan zero value untuk setiap hasil lainnya (0, "", nil). Pola lengkapnya, termasuk wrapping dan pemeriksaan, ada di halaman penanganan error.
Idiom comma-ok
Beberapa operasi bawaan mengembalikan bool kedua yang opsional, yang menyatakan apakah nilai pertama benar-benar ada. Variabelnya biasanya dinamai ok.
Ketiga bentuk ini (pencarian di map, type assertion, penerimaan dari channel) istimewa: mereka mengembalikan satu atau dua nilai tergantung berapa variabel yang kamu assign. Fungsi buatanmu sendiri tidak bisa begitu. Fungsi yang dideklarasikan dengan dua hasil selalu mengembalikan dua.
Blank identifier
_ menerima sebuah nilai lalu membuangnya. Pakai untuk hasil yang tidak kamu butuhkan:
_, err := fmt.Sscan(input, &n)
key, _ := parseLine(line)
Mengabaikan error dengan _ tetap bisa dikompilasi, jadi lakukan hanya kalau kamu tahu pemanggilannya tidak mungkin gagal atau kegagalannya tidak berpengaruh. Misalnya, strings.Builder.WriteString selalu mengembalikan error nil; menutup file setelah menulis tidak begitu.
Named result
Parameter hasil bisa diberi nama. Parameter ini dideklarasikan di awal fungsi, diinisialisasi dengan zero value, dan return tanpa nilai akan mengembalikan apa pun isinya saat itu.
Nama-nama itu muncul di output go doc, yang membantu saat dua hasil punya tipe yang sama: (quotient, remainder int) lebih informatif daripada (int, int).
return tanpa nilai di fungsi yang panjang sulit dibaca, karena pembaca harus menelusuri ke atas untuk melihat isi hasilnya. Saran yang umum: beri nama pada hasil kalau nama itu mendokumentasikan sesuatu, dan tetap tulis return quotient, remainder secara eksplisit kecuali fungsinya hanya beberapa baris.
Named result dan defer
Fungsi yang di-defer berjalan setelah pernyataan return mengisi hasilnya dan sebelum pemanggil menerimanya. Dengan named result, fungsi yang di-defer bisa membaca dan mengubah hasil itu. Beginilah cara menambahkan konteks ke error apa pun yang dikembalikan sebuah fungsi, atau mengubah panic menjadi error.
Program ini mencetak load : empty name lalu <nil>. return errors.New(...) lebih dulu meng-assign ke err, lalu fungsi yang di-defer membungkusnya. Selengkapnya di defer.
Shadowing pada named result
Named result berada di scope terluar fungsi. := di dalam blok bersarang membuat variabel baru dengan nama yang sama, lalu return tanpa nilai akan mengembalikan variabel yang di luar.
func find() (n int, err error) {
if true {
n, err := compute() // new n and err, shadowing the results
_ = n
_ = err
}
return // returns 0, nil
}
Compiler menangkap kasus terburuknya: return tanpa nilai di dalam blok tempat sebuah hasil di-shadow gagal dengan result parameter err not in scope at return. Compiler tidak menangkap versi di atas, yang return-nya berada di luar blok. Pakai = alih-alih := kalau yang kamu maksud adalah variabel hasil.
Kesalahan umum
- Memakai nilainya saat err tidak nil. Periksa
errdulu. Sebuah fungsi bebas mengembalikan nilai sampah bersama error. - Mengembalikan pointer nil bertipe sebagai error.
var e *MyErr; return emengembalikanerroryang tidak nil. Kembalikannilliteral saat sukses. - Terlalu banyak hasil. Tiga hasil atau lebih dengan makna yang bercampur sulit dipakai. Kembalikan struct sebagai gantinya.
Pertanyaan yang sering diajukan
Bagaimana cara mengembalikan beberapa nilai dari fungsi di Go?
Tulis tipe-tipe hasilnya di dalam tanda kurung, lalu kembalikan nilainya dipisahkan koma: func minMax(xs []int) (int, int) { ...; return lo, hi }. Pemanggil menerima semuanya sekaligus: lo, hi := minMax(nums).
Bagaimana cara mengabaikan salah satu nilai kembalian di Go?
Assign ke blank identifier _: _, err := strconv.Atoi(s) atau n, _ := strconv.Atoi(s). Kamu tidak bisa menghilangkan sebuah nilai sama sekali: jumlah variabel di sebelah kiri harus sama dengan jumlah hasil.
Apa itu named return value di Go?
Parameter hasil yang punya nama, seperti func split(n int) (half, rest int). Nilai awalnya adalah zero value, bisa di-assign di dalam badan fungsi, dan return tanpa nilai akan mengembalikan nilai terkininya. Named result juga memungkinkan fungsi yang di-defer mengubah apa yang diterima pemanggil.
Apakah sebaiknya saya memakai naked return di Go?
Hanya di fungsi yang pendek. return tanpa nilai di fungsi yang panjang menyembunyikan apa yang dikembalikan dan memudahkan munculnya bug shadowing. Panduan gaya Go menyarankan memberi nama pada hasil untuk dokumentasi, dan tetap mengembalikan nilai secara eksplisit di fungsi yang lebih dari beberapa baris.