go语言并没有自带支持三目运算. 所以我从github找到了一个对应的可使用的包, github.com/ymzuiku/hit, 确实可以满足大部分开发场景中的三目运算操作.

但是! 我在最近更换工作后, 与新同事就golang到底是否需要使用该包产生了一些分歧, 大体如下

  • golang 本身没有实现三目运算, 所以不要使用该操作包
  • 使用该包会影响代码可读性, 因为嵌套式三目运算可读性下降
  • 性能下降. 因该包使用了reflect, 造成代码执行性能下降

就以上问题. 我整理了一天的资料. 最终确认golang中不建议使用该类型包.

首选, 官方给出的结论https://golang.org/doc/faq#Does_Go_have_a_ternary_form

The reason ?: is absent from Go is that the language’s designers had seen the operation used too often to create impenetrably complex expressions. The if-else form, although longer, is unquestionably clearer. A language needs only one conditional control flow construct.

首先明确, golang只有一种通用判断语句if-else

其次, 语言层面没有提供三目运算, 通过自定义函数的形势实现基础a or b的能力是可以行的. 但! 三目运算本质上是一个惰性加载的过程, 并不是a,b的运行结果返回.
所以, 对没有考虑清楚的前提下, 以下代码是存在必然问题的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 我想实现如下功能

func a() int{
var num = 0
var result int
for num <= 10000{
num ++
if num % 2 ==0{
result += 1
}else{
result += 2
}
}
return result
}

让我们将其转换成hit.If

1
2
3
4
5
6
7
8
9
10
func aBug() int{
var num = 0
var result int

for num <= 10000{
num ++
hit.If(num % 2 ==0, result + 1, result + 2)
}
return result
}

发现问题了吗? 在aBug函数中有明显的bug, 那就是在判断前, result+1和result+2都进行了一次操作

Why? 为什么会是这个结果呢?

在我们通过函数来接受参数的时候, 实际上拿到的是一个函数/对象的操作结果/指针或引用. 那么实际上我们并不是根据判断来操作了该值, 对result进行+1或+2的操作
所以. 我们实际上不管他操作了每次循环都对result进行了+3的操作.

其三, 在go对if-else与hit.If进行benchmark性能测试后, 发现该操作在benchmark下, hit.If性能要低于原生语句5倍左右的性能.

综上三方面可以得到响应的结果.在我们使用go语言编程时,不建议各位实现该类型操作的函数

如果确实想使用类似功能可以封装一下util函数, 如

1
2
3
4
5
6
func StateErrorOrOk(ret int, msg string) *entity.State{
if ret != 0{
return &entity.State{Msg: msg, Code: ret}
}
return &entity.State{Msg: "SUCCEED", Code: 0}
}