Передмова: Не сперечаючись, що if else
це шлях, ми все ще можемо грати і знаходити задоволення в мовних конструкціях.
Наступна If
конструкція доступна в моїй github.com/icza/gox
бібліотеці з багатьма іншими методами, як builtinx.If
тип.
Go дозволяє приєднувати методи до будь -яких визначених користувачем типів , включаючи примітивні типи, такі як bool
. Ми можемо створити користувацький тип, що bool
є його основним типом , і тоді, за умови простого перетворення типу , ми маємо доступ до його методів. Методи, які отримують та вибирають із операндів.
Щось на зразок цього:
type If bool
func (c If) Int(a, b int) int {
if c {
return a
}
return b
}
Як ми можемо ним користуватися?
i := If(condition).Int(val1, val2) // Short variable declaration, i is of type int
|-----------| \
type conversion \---method call
Наприклад, що робить потрійний max()
:
i := If(a > b).Int(a, b)
Трійця робить abs()
:
i := If(a >= 0).Int(a, -a)
Це виглядає круто, це просто, елегантно та ефективно (воно також підходить для вставки ).
Один мінус порівняно з "справжнім" потрійним оператором: він завжди оцінює всі операнди.
Для досягнення відкладеної та лише за потреби оцінки, єдиним варіантом є використання функцій (або оголошених функцій або методів, або функціональних літералів ), які викликаються лише тоді, коли / якщо потрібно:
func (c If) Fint(fa, fb func() int) int {
if c {
return fa()
}
return fb()
}
Використовуючи це: Припустимо, у нас є ці функції для обчислення a
та b
:
func calca() int { return 3 }
func calcb() int { return 4 }
Тоді:
i := If(someCondition).Fint(calca, calcb)
Наприклад, умова поточного року> 2020:
i := If(time.Now().Year() > 2020).Fint(calca, calcb)
Якщо ми хочемо використовувати функціональні літерали:
i := If(time.Now().Year() > 2020).Fint(
func() int { return 3 },
func() int { return 4 },
)
Заключне зауваження: якщо у вас були функції з різними підписами, ви не можете їх використовувати тут. У такому випадку ви можете використовувати буквальний функцію з відповідним підписом, щоб зробити їх все ще застосовними.
Наприклад, якщо calca()
і calcb()
буде мати параметри (крім поверненого значення):
func calca2(x int) int { return 3 }
func calcb2(x int) int { return 4 }
Ось як ви могли їх використовувати:
i := If(time.Now().Year() > 2020).Fint(
func() int { return calca2(0) },
func() int { return calcb2(0) },
)
Спробуйте ці приклади на майданчику Go .