How to do one-liner if else statement?
我可以在go(golang)中编写一个带有变量赋值的if-else语句吗,就像在php中那样(例如):
1 | $var = ( $a > $b )? $a: $b; |
目前我必须使用以下方法:
1 2 3 4 5 6 | var c int if a > b { c = a } else { c = b } |
很抱歉,如果这个控制语句和在站点和谷歌搜索中找不到信息,我就记不起它的名字了。:
正如评论所提到的,Go不支持三元一行。我能想到的最短形式是:
1 2 3 4 | var c int if c = b; a > b { c = a } |
我经常使用以下方法:
1 2 3 4 | c := b if a > b { c = a } |
基本上与@not_a_golfer's相同,但使用类型推断。
正如其他人提到的,
1 2 3 4 5 6 7 | // IfThenElse evaluates a condition, if true returns the first parameter otherwise the second func IfThenElse(condition bool, a interface{}, b interface{}) interface{} { if condition { return a } return b } |
下面是一些测试案例,演示如何使用它
1 2 3 4 5 | func TestIfThenElse(t *testing.T) { assert.Equal(t, IfThenElse(1 == 1,"Yes", false),"Yes") assert.Equal(t, IfThenElse(1 != 1, nil, 1), 1) assert.Equal(t, IfThenElse(1 < 2, nil,"No"), nil) } |
为了好玩,我写了一些更有用的实用功能,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | IfThen(1 == 1,"Yes") //"Yes" IfThen(1 != 1,"Woo") // nil IfThen(1 < 2,"Less") //"Less" IfThenElse(1 == 1,"Yes", false) //"Yes" IfThenElse(1 != 1, nil, 1) // 1 IfThenElse(1 < 2, nil,"No") // nil DefaultIfNil(nil, nil) // nil DefaultIfNil(nil,"") //"" DefaultIfNil("A","B") //"A" DefaultIfNil(true,"B") // true DefaultIfNil(1, false) // 1 FirstNonNil(nil, nil) // nil FirstNonNil(nil,"") //"" FirstNonNil("A","B") //"A" FirstNonNil(true,"B") // true FirstNonNil(1, false) // 1 FirstNonNil(nil, nil, nil, 10) // 10 FirstNonNil(nil, nil, nil, nil, nil) // nil FirstNonNil() // nil |
如果您想使用其中任何一个,可以在这里找到它们:https://github.com/shomali11/util
感谢您指出正确的答案。
我刚刚查看了Golang FAQ(DUH),它清楚地表明,这是不可用的语言:
Does Go have the ?: operator?
There is no ternary form in Go. You may use the following to achieve the same result:
1
2
3
4
5 if expr {
n = trueVal
} else {
n = falseVal
}
发现可能对该主题感兴趣的其他信息:
- Go中条件结构的Rosetta代码
- 这家伙的围棋实验中的三元运算符
一种可能的方法是使用地图在一行中完成这项工作,简单地说,我正在检查
1 | c := map[bool]int{true: a, false: b}[a > b] |
然而,这看起来很神奇,但在某些情况下,由于评估顺序的原因,它可能不是完美的解决方案。例如,如果我正在检查一个对象是否不是
1 2 3 4 5 6 7 8 9 | type MyStruct struct { field1 string field2 string } var myObj *MyStruct myObj = nil myField := map[bool]string{true: myObj.field1, false:"empty!"}[myObj != nil} |
因为地图将在评估条件之前先创建和构建,所以在
别忘了,您仍然可以只在一行中完成这些条件,请检查以下内容:
1 2 3 | var c int ... if a > b { c = a } else { c = b} |
有时,我尝试使用匿名函数来实现在同一行中定义和分配。如下所示:
1 2 3 4 5 6 7 8 | a, b = 4, 8 c := func() int { if a >b { return a } return b } () |
https://play.golang.org/p/rmjqytmyeq0
您可以为此使用一个闭包:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | func doif(b bool, f1, f2 func()) { switch{ case b: f1() case !b: f2() } } func dothis() { fmt.Println("Condition is true") } func dothat() { fmt.Println("Condition is false") } func main () { condition := true doif(condition, func() { dothis() }, func() { dothat() }) } |
在go中,我对闭包语法唯一的抱怨是没有默认的零参数零返回函数的别名,那么它会更好(想想如何只用一个类型名声明map、array和slice文本)。
甚至是较短的版本,正如一位评论者所建议的那样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | func doif(b bool, f1, f2 func()) { switch{ case b: f1() case !b: f2() } } func dothis() { fmt.Println("Condition is true") } func dothat() { fmt.Println("Condition is false") } func main () { condition := true doif(condition, dothis, dothat) } |
如果需要为函数提供参数,仍然需要使用闭包。在传递方法的情况下可以避免这种情况,而不仅仅是我认为的函数,其中参数是与方法关联的结构。
语言中有非常相似的结构
1 2 3 4 5 | **if <statement>; <evaluation> { [statements ...] } else { [statements ...] }* |
*
即
1 2 3 4 5 | if path,err := os.Executable(); err != nil { log.Println(err) } else { log.Println(path) } |