How to do one-liner if else statement?

If StatementGoConditional OperatorTernary

If Statement Problem Overview


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. :/

If Statement Solutions


Solution 1 - If Statement

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.

Solution 2 - If Statement

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, "Yes", false), "Yes")
    assert.Equal(t, IfThenElse(1 != 1, nil, 1), 1)
    assert.Equal(t, IfThenElse(1 < 2, nil, "No"), nil)
}

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

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

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

Solution 3 - If Statement

I often use the following:

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

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

Solution 4 - If Statement

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:

Solution 5 - If Statement

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

c := map[bool]int{true: a, false: b}[a > 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: "empty!"}[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 > b { c = a } else { c = b}

Solution 6 - If Statement

A very similar construction is available in the language

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

*

i.e.

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

Solution 7 - If Statement

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>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 (
	"errors"
	"log"
	"os"
)

// 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't return empty string
	// reusing my favourite `must` helper
	// Isn't that kinda creepy now though?
	must(func() error {
		var err error
		if len(tmpDir) > 0 {
			err = nil
		} else {
			err = errors.New("os.TempDir is empty")
		}
		return err
	}()) // Don't forget that empty parentheses to invoke the lambda.
	println("We happy with", tmpDir)
}

Solution 8 - If Statement

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 >b {
      return a
    } 
    return b
  } ()

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

Solution 9 - If Statement

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

if <statement>; <evaluation> {
    [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("NUMBER"); v != "" {
   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("foo.png");
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("NUMBER"); v != "" {
    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.

Solution 10 - If Statement

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("Condition is true") }

func dothat() { fmt.Println("Condition is false") }

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("Condition is true") }

func dothat() { fmt.Println("Condition is false") }

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.

Solution 11 - If Statement

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 "math"

...

c := math.Max(a, b)

Solution 12 - If Statement

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionthorocView Question on Stackoverflow
Solution 1 - If StatementNot_a_GolferView Answer on Stackoverflow
Solution 2 - If StatementRaed ShomaliView Answer on Stackoverflow
Solution 3 - If StatementxoyuzView Answer on Stackoverflow
Solution 4 - If StatementthorocView Answer on Stackoverflow
Solution 5 - If StatementMuhammad SolimanView Answer on Stackoverflow
Solution 6 - If Statementuser2680100View Answer on Stackoverflow
Solution 7 - If StatementAlice VixieView Answer on Stackoverflow
Solution 8 - If StatementRonView Answer on Stackoverflow
Solution 9 - If StatementIgor FagundesView Answer on Stackoverflow
Solution 10 - If StatementLouki SumirniyView Answer on Stackoverflow
Solution 11 - If StatementEdson MedinaView Answer on Stackoverflow
Solution 12 - If StatementLaxmikant TiwariView Answer on Stackoverflow