引言:三元运算符——朋友还是敌人?
\n\n如果您是从C、C++、Java或JavaScript的世界来到Go语言,您一定习惯了简洁的构造:
\n\nint max = (a > b) ? a : b;\n\n这就是三元运算符。它紧凑、优雅,允许您将简单的分支逻辑写在一行中。但当您开始用Go编写代码时,您会迎来一个惊喜:Go语言中没有三元运算符。完全没有。没有任何? :。
为什么语言的设计者要这样做?现在如何编写简短的条件赋值?最重要的是,如何以符合语言习惯的方式——即Go社区所接受的风格——来做到这一点?
\n\n在本文中,我们将探讨:
\n- \n
- 为什么Go语言没有三元运算符(剧透:这是一个有意识的设计决定)。 \n
- 如何使用
if-else替代三元运算符。 \n - 进阶技巧:函数、map、内联。 \n
- 何时可以(并且应该)打破规则。 \n
我们开始吧!
\n\n为什么Go语言放弃了三元运算符?
\n\n答案很简单,源于该语言的哲学:可读性比简洁性更重要。
\n\n罗伯特·格瑞史莫(Go语言的创始人之一)曾说过:“三元运算符是bug的源头。它太容易被误读,尤其是当它被嵌套时”。这是事实。想想C语言中那个著名的例子:
\n\nint x = (a ? b : c) ? d : e;\n\n您能一眼看出它在做什么吗?Go语言的创建者们正是决定,与其牺牲一行代码,不如让代码清晰明了。
\n\n在Go语言中,优先级是意图的清晰性。如果您要编写一个条件,就让它显式地表达出来。三元运算符常常会变成“魔法数字”:您看着一行代码,却不能立即理解其逻辑。在Go语言中,这种情况不应该发生。
\n\n基本替代方案:if-else作为惯用写法
\n\n替代三元运算符最简单、最正确的方法是使用普通的if-else。是的,这需要3行代码而不是1行,但阅读起来毫不费力。
示例:找出两个数中的最大值。
\n\n在C语言中:
\nint max = (a > b) ? a : b;\n\n在Go语言中(符合语言习惯):
\nvar max int\nif a > b {\n max = a\n} else {\n max = b\n}\n\n“但这更长了!”您可能会说。是的。但请从另一个角度来看:一个月后,您打开这段代码,会立即看到逻辑。没有括号,没有歧义。只是“如果a大于b,则max = a,否则max = b”。
\n\n此外,Go社区认为这种风格对于简单条件是唯一正确的。不要试图“耍小聪明”把所有内容塞进一行——这会被认为是糟糕的风格。
\n\n进阶技巧:当您想要简洁时
\n\n有时您编写的代码中,if-else会占用10行,尽管本质上只是一个简单的赋值。在这种情况下,可以应用几种模式,它们既能保持符合语言习惯,又能使代码更紧凑。
1. 辅助函数
\n\n如果您经常需要在两个值之间进行选择,可以将逻辑提取到一个函数中。这对于单行操作尤其方便。
\n\nfunc ternary(cond bool, a, b string) string {\n if cond {\n return a\n }\n return b\n}\n\n// 使用方式:\ngreeting := ternary(isMorning, "早上好", "晚上好")\n\n重要提示:不要将函数命名为ternary——这被认为是不好的做法,因为您试图通过后门“偷渡”三元运算符。最好给它一个有意义的名称,例如ifElse或choose。但如果您是为自己编写代码,那又何妨呢?
2. 使用map进行选择
\n\n如果条件归结为从两个选项中选择一个,可以使用布尔键的map。这看起来不寻常,但有时可读性甚至更好。
\n\nvar result = map[bo