Kata Pengantar: Tanpa berdebat bahwa if else
ini adalah jalan yang harus ditempuh, kita masih dapat bermain dan menemukan kesenangan dalam konstruksi yang didukung bahasa.
If
Konstruk berikut tersedia di github.com/icza/gox
perpustakaan saya dengan banyak metode lain, sebagai builtinx.If
tipenya.
Go memungkinkan untuk melampirkan metode ke tipe yang ditentukan pengguna , termasuk tipe primitif seperti bool
. Kita dapat membuat tipe kustom yang memiliki bool
sebagai tipe yang mendasarinya , dan kemudian dengan konversi tipe sederhana pada kondisi tersebut, kita memiliki akses ke metode-metodenya. Metode yang menerima dan memilih dari operan.
Sesuatu seperti ini:
type If bool
func (c If) Int(a, b int) int {
if c {
return a
}
return b
}
Bagaimana kita bisa menggunakannya?
i := If(condition).Int(val1, val2) // Short variable declaration, i is of type int
|-----------| \
type conversion \---method call
Misalnya seorang ternary melakukan max()
:
i := If(a > b).Int(a, b)
Seorang ternary melakukan abs()
:
i := If(a >= 0).Int(a, -a)
Ini terlihat keren, sederhana, elegan, dan efisien (ini juga memenuhi syarat untuk inlining ).
Satu kelemahan dibandingkan dengan operator ternary "nyata": selalu mengevaluasi semua operan.
Untuk mencapai evaluasi yang ditangguhkan dan hanya-jika-diperlukan, satu-satunya pilihan adalah menggunakan fungsi (baik fungsi atau metode yang dideklarasikan , atau fungsi literal ), yang hanya dipanggil ketika / jika diperlukan:
func (c If) Fint(fa, fb func() int) int {
if c {
return fa()
}
return fb()
}
Menggunakannya: Mari kita asumsikan kita memiliki fungsi-fungsi ini untuk menghitung a
dan b
:
func calca() int { return 3 }
func calcb() int { return 4 }
Kemudian:
i := If(someCondition).Fint(calca, calcb)
Misalnya, kondisi menjadi tahun berjalan> 2020:
i := If(time.Now().Year() > 2020).Fint(calca, calcb)
Jika kita ingin menggunakan fungsi literal:
i := If(time.Now().Year() > 2020).Fint(
func() int { return 3 },
func() int { return 4 },
)
Catatan akhir: jika Anda akan memiliki fungsi dengan tanda tangan yang berbeda, Anda tidak dapat menggunakannya di sini. Dalam hal ini Anda dapat menggunakan fungsi literal dengan tanda tangan yang cocok untuk membuatnya masih berlaku.
Misalnya jika calca()
dan calcb()
akan memiliki parameter juga (selain nilai balik):
func calca2(x int) int { return 3 }
func calcb2(x int) int { return 4 }
Ini adalah bagaimana Anda dapat menggunakannya:
i := If(time.Now().Year() > 2020).Fint(
func() int { return calca2(0) },
func() int { return calcb2(0) },
)
Cobalah contoh-contoh ini di Go Playground .