如何使用一行代码实现if-else语句?

huangapple go评论130阅读模式
英文:

How to do one-liner if else statement?

问题

请参考@accdias指出的https://golangdocs.com/ternary-operator-in-golang

我能否像在php中那样,在go(golang)中编写一个简单的带有变量赋值的if-else语句?例如:

$var = ( $a > $b )? $a: $b;

目前我需要使用以下代码:

var c int
if a > b {
    c = a
} else {
    c = b
}

抱歉,我记不起这个控制语句的名字,我在网站上和谷歌搜索中都找不到相关信息。:/

英文:

Please see https://golangdocs.com/ternary-operator-in-golang as pointed by @accdias (see comments)

Can I write a simple if-else statement with variable assignment in go (golang) as I would do in php? For example:

$var = ( $a > $b )? $a: $b;

Currently I have to use the following:

var c int
if a > b {
    c = a
} else {
    c = b
}

Sorry I cannot remember the name if this control statement and I couldn't find the info in-site or through google search. :/

答案1

得分: 212

根据评论所提到的,Go语言不支持三元运算符。我能想到的最简短的形式是这样的:

var c int
if c = b; a > b {
	c = a
}

但请不要这样做,这不值得而且只会让阅读你代码的人感到困惑。

英文:

As the comments mentioned, Go doesn't support ternary one liners. The shortest form I can think of is this:

var c int
if c = b; a > b {
	c = a
}

But please don't do that, it's not worth it and will only confuse people who read your code.

答案2

得分: 46

如其他人所提到的,Go 不支持三元运算符一行写法。然而,我编写了一个实用函数可以帮助你实现你想要的效果。

// IfThenElse 根据条件判断,如果为真返回第一个参数,否则返回第二个参数
func IfThenElse(condition bool, a interface{}, b interface{}) interface{} {
    if condition {
        return a
    }
    return b
}

以下是一些测试用例,展示了如何使用该函数:

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)
}

为了好玩,我还编写了其他有用的实用函数,例如:

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

英文:

As the others mentioned, Go does not support ternary one-liners. However, I wrote a utility function that could help you achieve what you want.

// 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
}

Here are some test cases to show how you can use it

func TestIfThenElse(t *testing.T) {
    assert.Equal(t, IfThenElse(1 == 1, &quot;Yes&quot;, false), &quot;Yes&quot;)
    assert.Equal(t, IfThenElse(1 != 1, nil, 1), 1)
    assert.Equal(t, IfThenElse(1 &lt; 2, nil, &quot;No&quot;), nil)
}

For fun, I wrote more useful utility functions such as:

IfThen(1 == 1, &quot;Yes&quot;) // &quot;Yes&quot;
IfThen(1 != 1, &quot;Woo&quot;) // nil
IfThen(1 &lt; 2, &quot;Less&quot;) // &quot;Less&quot;

IfThenElse(1 == 1, &quot;Yes&quot;, false) // &quot;Yes&quot;
IfThenElse(1 != 1, nil, 1)       // 1
IfThenElse(1 &lt; 2, nil, &quot;No&quot;)     // nil

DefaultIfNil(nil, nil)  // nil
DefaultIfNil(nil, &quot;&quot;)   // &quot;&quot;
DefaultIfNil(&quot;A&quot;, &quot;B&quot;)  // &quot;A&quot;
DefaultIfNil(true, &quot;B&quot;) // true
DefaultIfNil(1, false)  // 1

FirstNonNil(nil, nil)                // nil
FirstNonNil(nil, &quot;&quot;)                 // &quot;&quot;
FirstNonNil(&quot;A&quot;, &quot;B&quot;)                // &quot;A&quot;
FirstNonNil(true, &quot;B&quot;)               // true
FirstNonNil(1, false)                // 1
FirstNonNil(nil, nil, nil, 10)       // 10
FirstNonNil(nil, nil, nil, nil, nil) // nil
FirstNonNil()                        // nil

If you would like to use any of these, you can find them here https://github.com/shomali11/util

答案3

得分: 37

我经常使用以下代码:

c := b
if a > b {
    c = a
}

基本上与 @Not_a_Golfer 的代码相同,但使用了类型推断。

英文:

I often use the following:

c := b
if a &gt; b {
    c = a
}

basically the same as @Not_a_Golfer's but using type inference.

答案4

得分: 26

感谢指出正确答案。

我刚刚查看了Golang FAQ(嗯),它明确说明该语言中没有这个操作符:

> Go语言有三元操作符吗?
>
> Go语言中没有三元形式。您可以使用以下方法来实现相同的结果:
>
> if expr {
> n = trueVal
> } else {
> n = falseVal
> }

还找到了一些可能与该主题相关的其他信息:

英文:

Thanks for pointing toward the correct answer.

I have just checked the Golang FAQ (duh) and it clearly states, this is not available in the language:

> Does Go have the ?: operator?
>
> There is no ternary form in Go. You may use the following to achieve the same result:
>
> if expr {
> n = trueVal
> } else {
> n = falseVal
> }

additional info found that might be of interest on the subject:

答案5

得分: 12

使用映射(map)可以在一行代码中实现这个目标,简单来说,我检查a > b是否为真,如果是真,我将c赋值为a,否则为b

c := map[bool]int{true: a, false: b}[a > b]

然而,这看起来很棒,但在某些情况下可能不是完美的解决方案,因为它涉及到评估顺序。例如,如果我检查一个对象是否不为nil,然后从中获取某个属性,看看下面的代码片段,如果myObj等于nil,它将会引发panic

type MyStruct struct {
   field1 string
   field2 string 
}

var myObj *MyStruct
myObj = nil 

myField := map[bool]string{true: myObj.field1, false: "empty!"}[myObj != nil]

因为在评估条件之前,映射将首先被创建和构建,所以在myObj = nil的情况下,这将简单地引发panic

还要注意的是,你仍然可以在一行简单的代码中进行条件判断,看看下面的示例:

var c int
...
if a > b { c = a } else { c = b }
英文:

One possible way to do this in just one line by using a map, simple I am checking whether a &gt; b if it is true I am assigning c to a otherwise b

c := map[bool]int{true: a, false: b}[a &gt; b]

However, this looks amazing but in some cases it might NOT be the perfect solution because of evaluation order. For example, if I am checking whether an object is not nil get some property out of it, look at the following code snippet which will panic in case of myObj equals nil

type MyStruct struct {
   field1 string
   field2 string 
}

var myObj *MyStruct
myObj = nil 

myField := map[bool]string{true: myObj.field1, false: &quot;empty!&quot;}[myObj != nil}

Because map will be created and built first before evaluating the condition so in case of myObj = nil this will simply panic.

Not to forget to mention that you can still do the conditions in just one simple line, check the following:

var c int
...
if a &gt; b { c = a } else { c = b}

答案6

得分: 4

一个非常类似的结构在语言中是可用的:

if <语句>; <条件> {
   [语句块 ...]
} else {
   [语句块 ...]
}

也就是说:

if path,err := os.Executable(); err != nil {
   log.Println(err)
} else {
   log.Println(path)
}
英文:

A very similar construction is available in the language

**if &lt;statement&gt;; &lt;evaluation&gt; {
   [statements ...]
} else {
   [statements ...]
}*

*

i.e.

if path,err := os.Executable(); err != nil {
   log.Println(err)
} else {
   log.Println(path)
}

答案7

得分: 3

使用lambda函数代替三元运算符

示例1

给出最大整数

package main

func main() {

	println(func(a, b int) int { if a > b { return a } else { return b } }(1, 2))
}

示例2

假设你有一个must(err error)函数来处理错误,并且当条件不满足时你想要使用它。
(在https://play.golang.com/p/COXyo0qIslP上查看)

package main

import (
	"errors"
	"log"
	"os"
)

// must是一个处理错误的小助手函数。如果传入的错误不为nil,它会简单地引发panic。
func must(err error) {
	if err != nil {
		log.Println(err)
		panic(err)
	}
}

func main() {

	tmpDir := os.TempDir()
	// 确保os.TempDir没有返回空字符串
	// 重用我最喜欢的`must`助手
	// 现在这不是有点可怕吗?
	must(func() error {
		var err error
		if len(tmpDir) > 0 {
			err = nil
		} else {
			err = errors.New("os.TempDir为空")
		}
		return err
	}()) // 不要忘记使用空括号调用lambda函数。
	println("我们满意于", tmpDir)
}
英文:

Use lambda function instead of ternary operator

Example 1

to give the max int

package main

func main() {

	println( func(a,b int) int {if a&gt;b {return a} else {return b} }(1,2) )
}

Example 2

Suppose you have this must(err error) function to handle errors and you want to use it when a condition isn't fulfilled.
(enjoy at https://play.golang.com/p/COXyo0qIslP)

package main

import (
	&quot;errors&quot;
	&quot;log&quot;
	&quot;os&quot;
)

// must is a little helper to handle errors. If passed error != nil, it simply panics.
func must(err error) {
	if err != nil {
		log.Println(err)
		panic(err)
	}
}

func main() {

	tmpDir := os.TempDir()
	// Make sure os.TempDir didn&#39;t return empty string
	// reusing my favourite `must` helper
	// Isn&#39;t that kinda creepy now though?
	must(func() error {
		var err error
		if len(tmpDir) &gt; 0 {
			err = nil
		} else {
			err = errors.New(&quot;os.TempDir is empty&quot;)
		}
		return err
	}()) // Don&#39;t forget that empty parentheses to invoke the lambda.
	println(&quot;We happy with&quot;, tmpDir)
}

答案8

得分: 2

有时候,我尝试使用匿名函数来实现在同一行定义和赋值。就像下面这样:

a, b = 4, 8

c := func() int {
    if a > b {
      return a
    } 
    return b
  } ()

链接:https://play.golang.org/p/rMjqytMYeQ0

英文:

Sometimes, I try to use anonymous function to achieve defining and assigning happen at the same line. like below:

a, b = 4, 8

c := func() int {
    if a &gt;b {
      return a
    } 
    return b
  } ()

https://play.golang.org/p/rMjqytMYeQ0

答案9

得分: 2

像user2680100所说,在Golang中,你可以使用以下结构:

if <statement>; <evaluation> {
    [statements ...]
} else {
    [statements ...]
}

这对于简化一些需要错误检查或其他类型的布尔检查的表达式非常有用,例如:

var number int64
if v := os.Getenv("NUMBER"); v != "" {
   if number, err = strconv.ParseInt(v, 10, 64); err != nil {
       os.Exit(42)
   }
} else {
    os.Exit(1)
}

使用这种方式,你可以实现类似于C语言中的操作:

Sprite *buffer = get_sprite("foo.png");
Sprite *foo_sprite = (buffer != 0) ? buffer : donut_sprite;

但是显然,在Golang中,这种语法糖需要适度使用。对我个人而言,我喜欢在最多一层嵌套中使用这种语法糖,例如:

var number int64
if v := os.Getenv("NUMBER"); v != "" {
    number, err = strconv.ParseInt(v, 10, 64)
    if err != nil {
        os.Exit(42)
    }
} else {
    os.Exit(1)
}

你还可以使用类似于func Ternary(b bool, a interface{}, b interface{}) { ... }的函数来实现三元表达式,但我不喜欢这种方法,它看起来像是在语法中创建了一个异常情况,并且在我个人看来,这种"特性"会降低对算法和可读性的关注。但是,我不选择这种方式的最重要的原因是它可能会带来一定的开销,并在程序执行中增加更多的循环。

英文:

Like user2680100 said, in Golang you can have the structure:

if &lt;statement&gt;; &lt;evaluation&gt; {
    [statements ...]
} else {
    [statements ...]
}

This is useful to shortcut some expressions that need error checking, or another kind of boolean checking, like:


var number int64
if v := os.Getenv(&quot;NUMBER&quot;); v != &quot;&quot; {
   if number, err = strconv.ParseInt(v, 10, 64); err != nil {
       os.Exit(42)
   }
} else {
    os.Exit(1)
}

With this you can achieve something like (in C):

Sprite *buffer = get_sprite(&quot;foo.png&quot;);
Sprite *foo_sprite = (buffer != 0) ? buffer : donut_sprite

But is evident that this sugar in Golang have to be used with moderation, for me, personally, I like to use this sugar with max of one level of nesting, like:


var number int64
if v := os.Getenv(&quot;NUMBER&quot;); v != &quot;&quot; {
    number, err = strconv.ParseInt(v, 10, 64)
    if err != nil {
        os.Exit(42)
    }
} else {
    os.Exit(1)
}

You can also implement ternary expressions with functions like func Ternary(b bool, a interface{}, b interface{}) { ... } but i don't like this approach, looks like a creation of a exception case in syntax, and creation of this "features", in my personal opinion, reduce the focus on that matters, that is algorithm and readability, but, the most important thing that makes me don't go for this way is that fact that this can bring a kind of overhead, and bring more cycles to in your program execution.

答案10

得分: 0

你可以使用闭包来实现这个功能:

func doif(b bool, f1, f2 func()) {
    switch {
    case b:
        f1()
    case !b:
        f2()
    }
}

func dothis() { fmt.Println("条件为真") }

func dothat() { fmt.Println("条件为假") }

func main() {
    condition := true
    doif(condition, func() { dothis() }, func() { dothat() })
}

我对Go语言中闭包语法的唯一抱怨是没有为默认的零参数零返回函数提供别名,如果有的话会更好(类似于如何只使用类型名称声明映射、数组和切片字面量)。

或者,正如一位评论者刚刚建议的那样,还可以使用更简短的版本:

func doif(b bool, f1, f2 func()) {
    switch {
    case b:
        f1()
    case !b:
        f2()
    }
}

func dothis() { fmt.Println("条件为真") }

func dothat() { fmt.Println("条件为假") }

func main() {
    condition := true
    doif(condition, dothis, dothat)
}

如果需要向函数传递参数,仍然需要使用闭包。如果传递的是方法而不仅仅是函数,我认为可以省略这一点,其中参数是与方法关联的结构体。

英文:

You can use a closure for this:

func doif(b bool, f1, f2 func()) {
    switch{
    case b:
        f1()
    case !b:   
        f2()
    }
}

func dothis() { fmt.Println(&quot;Condition is true&quot;) }

func dothat() { fmt.Println(&quot;Condition is false&quot;) }

func main () {
    condition := true
    doif(condition, func() { dothis() }, func() { dothat() })
}

The only gripe I have with the closure syntax in Go is there is no alias for the default zero parameter zero return function, then it would be much nicer (think like how you declare map, array and slice literals with just a type name).

Or even the shorter version, as a commenter just suggested:

func doif(b bool, f1, f2 func()) {
    switch{
    case b:
        f1()
    case !b:   
        f2()
    }
}

func dothis() { fmt.Println(&quot;Condition is true&quot;) }

func dothat() { fmt.Println(&quot;Condition is false&quot;) }

func main () {
    condition := true
    doif(condition, dothis, dothat)
}

You would still need to use a closure if you needed to give parameters to the functions. This could be obviated in the case of passing methods rather than just functions I think, where the parameters are the struct associated with the methods.

答案11

得分: -1

正如其他人指出的那样,Go语言中没有三元运算符。

不过对于你的特定示例,如果你想要使用一行代码,你可以使用Max函数。

import "math"

...

c := math.Max(a, b)
英文:

As everyone else pointed out, there's no ternary operator in Go.

For your particular example though, if you want to use a single liner, you could use Max.

import &quot;math&quot;

...

c := math.Max(a, b)

答案12

得分: -6

三元运算符的替代方案 | golang if else 一行代码
在Go语言中,你不能编写一个简短的一行条件语句;因为没有三元条件运算符。
了解更多关于Golang的if..else语句

英文:

Ternary ? operator alternatives | golang if else one line
You can’t write a short one-line conditional in Go language ; there is no ternary conditional operator.
Read more about if..else of Golang

huangapple
  • 本文由 发表于 2014年10月24日 18:09:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/26545883.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定