在C/ c++(以及该家族的许多语言)中,根据条件声明和初始化变量的常用习语使用三元条件操作符:
int index = val > 0 ? val : -val
Go没有条件运算符。实现上面同一段代码的最惯用的方法是什么?我想出了下面的解决方案,但它似乎相当啰嗦
var index int
if val > 0 {
index = val
} else {
index = -val
}
还有更好的办法吗?
在C/ c++(以及该家族的许多语言)中,根据条件声明和初始化变量的常用习语使用三元条件操作符:
int index = val > 0 ? val : -val
Go没有条件运算符。实现上面同一段代码的最惯用的方法是什么?我想出了下面的解决方案,但它似乎相当啰嗦
var index int
if val > 0 {
index = val
} else {
index = -val
}
还有更好的办法吗?
当前回答
关于三元运算符的惯用方法,还有一个建议:
package main
import (
"fmt"
)
func main() {
val := -5
index := func (test bool, n, d int) int {
if test {
return n
}
return d
}(val > 0, val, -val)
fmt.Println(index)
}
去操场
其他回答
虽然被创作者所回避,但俏皮话也有自己的一席之地。
这个函数解决了惰性求值的问题,它允许你在必要时可选地传递函数来求值:
func FullTernary(e bool, a, b interface{}) interface{} {
if e {
if reflect.TypeOf(a).Kind() == reflect.Func {
return a.(func() interface{})()
}
return a
}
if reflect.TypeOf(b).Kind() == reflect.Func {
return b.(func() interface{})()
}
return b
}
func demo() {
a := "hello"
b := func() interface{} { return a + " world" }
c := func() interface{} { return func() string { return "bye" } }
fmt.Println(FullTernary(true, a, b).(string)) // cast shown, but not required
fmt.Println(FullTernary(false, a, b))
fmt.Println(FullTernary(true, b, a))
fmt.Println(FullTernary(false, b, a))
fmt.Println(FullTernary(true, c, nil).(func() string)())
}
输出
hello
hello world
hello world
hello
bye
传入的函数必须返回一个接口{}以满足内部强制转换操作。 根据上下文,您可以选择将输出强制转换为特定类型。 如果你想从这个函数中返回一个函数,你需要用c来包装它。
这里的独立解决方案也很好,但对于某些用途可能不太清楚。
No Go没有三元运算符。使用if/else语法是惯用的方法。
Why does Go not have the ?: operator? There is no ternary testing operation in Go. You may use the following to achieve the same result: if expr { n = trueVal } else { n = falseVal } 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. — Frequently Asked Questions (FAQ) - The Go Programming Language
关于三元运算符的惯用方法,还有一个建议:
package main
import (
"fmt"
)
func main() {
val := -5
index := func (test bool, n, d int) int {
if test {
return n
}
return d
}(val > 0, val, -val)
fmt.Println(index)
}
去操场
假设你有以下三元表达式(C语言):
int a = test ? 1 : 2;
在Go中惯用的方法是简单地使用if块:
var a int
if test {
a = 1
} else {
a = 2
}
但是,这可能不符合您的要求。在我的例子中,我需要一个代码生成模板的内联表达式。
我使用了一个立即求值的匿名函数:
a := func() int { if test { return 1 } else { return 2 } }()
这确保了两个分支都不会被计算。
现在随着go1.18泛型的发布,使用这样的泛型函数非常容易,而且它在整个应用程序中都是可重用的
package main
import (
"fmt"
)
func Ternary[T any](condition bool, If, Else T) T {
if condition {
return If
}
return Else
}
func main() {
fmt.Println(Ternary(1 < 2, "yes", "no")) // yes
fmt.Println(Ternary(1 < 2, 1, 0)) // 1
fmt.Println(Ternary[bool](1 < 2, true, false)) // true
}
注意,如果在这种情况下使用它,它会崩溃。 在这种情况下,只需使用if语句, (因为你传递给函数的是nil指针而不是if语句,如果它是假的就不会调用该section)
var a *string
fmt.Println(Ternary(a != nil, *a, "some thing else"))
解决方案使用函数调用它,因此如果它为false,它将不会被执行
func TernaryPointer[T any](condition bool, If, Else func() T) T {
if condition {
return If()
}
return Else()
}
var pString *string
fmt.Println(TernaryPointer(
pString != nil, // condition
func() string { return *pString }, // true
func() string { return "new data" }, // false
))
但在这种情况下,我认为常规的if语句更干净(除非go在未来添加箭头函数) 操场上
相信这个答案,他已经回答了