SoFunction
Updated on 2025-03-05

Detailed explanation of why there is no ternary operator in golang

Tripartite operators are widely present in other languages, such as:

python:

val = trueValue if expr else falseValue

javascript:

const val = expr ? trueValue : falseValue

c、c++:

const char *val = expr ? "trueValue" : "falseValue";

However, the widely supported trigonometric operator does not exist in golang! If we write a code similar to the following:

val := expr ? "trueValue" : "falseValue"

Then the compiler should complain: invalid character U+003F '?'. It means that this operator does not exist in golang? The compiler does not recognize this operator and non-alphanumeric underscores cannot be used as variable names, so it is naturally regarded as illegal characters.

However, why is this? In fact, the official explanation is given. Here is a brief quote:

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.

The reason for the ?: operator is not present in golang is because language designers have predicted that ternary operators are often used to build extremely complex expressions. While using if for substitution will make the code appear longer, this is undoubtedly more readable. It is enough for a language to have only one conditional judgment structure.

There is no doubt that this is a product under the guiding ideology of golang's "the way is simple".

This passage is actually fine, because the usage scenarios of some ternary operators will indeed reduce the readability of the code:

const status = (type===1?(agagin===1?'Resell':'Sold'):'Unsold')

const word = ( === 0) ? 'a'
  : ( === 1 &&  > 3) ? 'b'
  : ( === 2 &&  > 5 && String().length > 5) ? 'c'
  : 'd';

At first glance, it is indeed very complicated. At least the second expression may not be able to sort out the control flow without taking 20 seconds to look at it carefully (imagine when the indent is misaligned or there is no indent at all).

If you convert them directly into if statements, it looks like this:

let status = ''
if (type === 1) {
  if (again === 1) {
    status = 'Resell'
  } else {
    status = 'Sold'
  }
} else {
  status = 'Unsold'
}

let word = ''
if ( === 0) {
  word = 'a'
} else {
  if ( === 1 &&  > 3) {
    word = 'b'
  } else {
    if ( === 2 &&  > 5 && String().length > 5) {
      word = 'c'
    } else {
      word = 'd'
    }
  }
}

It doesn't seem to be much improvement, especially in Example 2, three-layer nesting, no matter who reviews this code, it is inevitable that you will complain a few words.

However, in fact, these codes can be simplified. Considering that the ternary operator always gives a value to the variable, the last else can actually be regarded as the default value of the variable, so the code can be written like this:

let status = 'Unsold'
if (type === 1) {
  if (again === 1) {
    status = 'Resell'
  } else {
    status = 'Sold'
  }
}

let word = 'd'
if ( === 0) {
  word = 'a'
} else {
  if ( === 1 &&  > 3) {
    word = 'b'
  } else {
    if ( === 2 &&  > 5 && String().length > 5) {
      word = 'c'
    }
  }
}

Second, for Example 2, it is obvious that else if can be used to clear the nested structure:

let word = 'd'
if ( === 0) {
  word = 'a'
} else if ( === 1 &&  > 3) {
  word = 'b'
} else if ( === 2 &&  > 5 && String().length > 5) {
  word = 'c'
}

Now let's look at it again, obviously the version using if statements is more readable and the logic is clearer (by removing nesting).

However, the facts are not entirely true. In addition to using ternary operators to express process control, in fact, a more common and wider application is the following expression:

const val = expr ? trueValue : falseValue

const func = (age) => age > 18 ? 'Adult' : 'Minor'

Similar to the above, the value of a variable is determined by a short conditional expression, and the frequency of occurrence in development is quite high. At this time, the intention of the ternary operator is clearer and readable is higher than that of if statements. Especially when used with anonymous functions (lambda expressions) can greatly simplify our code.

The solution to this python is to support the above simplified version of the ternary expression, and the expression does not support nesting, which achieves the purpose of playing to the strengths and avoiding weaknesses. However, the price is that the relevant implementation of the compiler will be complicated.

For golang, a simple compiler that can complete ast construction through a single pass scan is one of the secrets to maintain rapid construction speed. It is unacceptable to increase the complexity of the compiler implementation for such a simple function. At the same time, due to the philosophy of golang's "the way is simple", problems that can be solved with existing grammatical structures will naturally not be added to new grammars.

But there is still a way, although it is not recommended:

func If(cond bool, a, b interface{}) {
  if cond {
    return a
  }

  return b
}

age := 20
val := If(age > 18, "Adults", "Minor").(string)

There are several reasons why this is not recommended:

  1. Use of interfaces leads to performance degradation
  2. Type assertions that require forced
  3. Regardless of ternary expressions or if statements, it will not be calculated for branches that will not arrive, that is, lazy calculation; and when passing parameters to a function, each expression will be calculated.

Finally, let’s summarize:

Advantages of ternary operators:

  • It is clearer to use ternary operators for short expressions, especially after getting used to reading ternary operator expressions in a linear way
  • No intermediate state is required (for example, the let variable in the first example can be replaced with const, the code is more robust), and the mental burden is lower
  • No intermediate state means fewer or no side effects, making the code easier to track and maintain

But the ternary operator also has obvious disadvantages:

  • For complex logical codes, poor readability (for example, status in the first example, when further conditional judgment is required at the location of trueValue)
  • It is easy to be abused, and many people use it to replace if statements or simplify complex if nesting, which leads to the results described in the previous article
  • Conditional branches can only be expressions and do not support multiple statements.

So this is a matter of opinion. In short, we can only follow the local customs.

refer to

/post/6844903561759850510

/zh/javascript/Replace nested ternary operator in js/1055944752/

/doc/faq#Does_Go_have_a_ternary_form

Summarize

This is the end of this article about why there is no ternary operator in golang. For more related contents of golang, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!