前言:不用争论那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 Playground上尝试这些示例。