C的三元运算符是什么?

在C / C ++(以及该族的许多语言)中,根据条件声明和初始化variables的常见习惯用法使用三元条件运算符:

int index = val > 0 ? val : -val 

Go没有条件运算符。 实现与上面相同的一段代码的最习惯的方式是什么? 我来到以下的解决scheme,但似乎很详细

 var index int if val > 0 { index = val } else { index = -val } 

有什么更好的吗?

正如所指出的(希望不出所料),使用if+else确实是在Go中使用条件语的惯用方式 。

除了完整的var+if+else代码块之外,这种拼写也经常被使用:

 index := val if val <= 0 { index = -val } 

如果你有一个足够重复的代码块,比如等价的int value = a <= b ? a : b int value = a <= b ? a : b ,你可以创build一个函数来保存它:

 func min(a, b int) int { if a <= b { return a } return b } ... value := min(a, b) 

编译器将内联这样简单的函数,所以它更快,更清晰,更短。

没有Go没有三元运算符,使用if / else语法惯用的方式: http : //golang.org/doc/faq#Does_Go_have_a_ternary_form

假设你有下面的三元expression式(C):

 int a = test ? 1 : 2; 

Go中的惯用方法是简单地使用if块:

 var a int if test { a = 1 } else { a = 2 } 

但是,这可能不符合您的要求。 在我的情况下,我需要一个代码生成模板的内联expression式。

我使用了一个立即评估的匿名函数:

 a := func() int { if test { return 1 } else { return 2 } }() 

这确保两个分支都不被评估。

三元地图很容易阅读,没有括号:

 c := map[bool]int{true: 1, false: 0} [5 > 4] 

如果你所有的分支都有副作用计算成本高昂,那么下面的语义保留重构:

 index := func() int { if val > 0 { return printPositiveAndReturn(val) } else { return slowlyReturn(-val) // or slowlyNegate(val) } }(); # exactly one branch will be evaluated 

通常没有开销(内联),而且最重要的是,不要使用只有一次使用的帮助函数(这会妨碍可读性和维护)混淆名称空间。 现场示例

请注意,如果你是天真地应用古斯塔沃的方法 :

  index := printPositiveAndReturn(val); if val <= 0 { index = slowlyReturn(-val); // or slowlyNegate(val) } 

你会得到一个不同的行为scheme ; 如果val <= 0程序将打印一个非正值,而不应该! (类似地,如果您颠倒了分支,则会通过不必要地调用慢速函数来引入开销。)

eold的答案很有意思,很有创意,甚至可能很聪明。

但是,build议您改为:

 var index int if val > 0 { index = printPositiveAndReturn(val) } else { index = slowlyReturn(-val) // or slowlyNegate(val) } 

是的,他们都编译到本质上相同的程序集,但是这个代码比调用一个匿名函数更易读,只是返回一个可能已经写入variables的值。

基本上,简单明了的代码比创意代码更好。

另外,任何使用地图文字的代码都不是一个好主意,因为在Go中地图不是轻量级的。 从Go 1.3开始,小地图的随机迭代顺序是有保证的,为了实现这一点,对于小地图来说,它的记忆效率要低得多。

因此,制作和删除大量的小地图既耗费空间又耗时。 我有一段使用小地图的代码(可能有两个或三个键,但常见用例只有一个条目),但是代码很慢。 我们所讲的速度至less要比使用双切片键[index] => data [index] map的相同代码慢3个数量级。 而且可能更多。 由于之前需要几分钟运行的一些操作,开始以毫秒为单位完成。

 func Ternary(statement bool, a, b interface{}) interface{} { if statement { return a } return b } func Abs(n int) int { return Ternary(n >= 0, n, -n).(int) } 

这不会超过如果/其他,并要求演员,但工程。 供参考:

BenchmarkAbsTernary-8 100000000 18.8 ns / op

BenchmarkAbsIfElse-8 2000000000 0.27 ns / op