Why there is no ternary operator in golang

Time:2021-4-30

Ternary operators are widely used in other languages

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 ternary operator does not exist in golang! If we write something like this:


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

So it’s time for the compiler to complain: invalid character U + 003f ‘?’. Doesn’t exist in golang? This operator is not recognized by the compiler, and non alphanumeric underscores cannot be used as variable names. Naturally, it is regarded as illegal characters.

However, why is this? In fact, the government has given an explanation. Here is a simple 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.

Does not exist in golang?: The reason is that language designers have foreseen that ternary operators are often used to build extremely complex expressions. Although using if as an alternative makes the code look longer, it’s undoubtedly more readable. A language needs only one conditional judgment structure.

There is no doubt that this is the product of golang’s guiding ideology of “great road to simplicity”.

In fact, this passage is not a problem, because the use of some ternary operators does reduce the readability of the code

const status = (type===1?( agagin===1?' Resale ':'sold'):'not sold ')

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

At first glance, it’s really complicated. At least the second expression may not be able to clarify the control process without taking 20 seconds (imagine when the indentation is misplaced or not at all).

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

let status = ''
if (type === 1) {
  if (again === 1) {
    Status ='resale '
  } else {
    Status ='sold '
  }
} else {
  Status ='not sold '
}

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

It seems that there is not much improvement, especially example 2, three-tier nesting. No matter who reviews this code, it will not complain about you.

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

Let status ='not sold '
if (type === 1) {
  if (again === 1) {
    Status ='resale '
  } else {
    Status ='sold '
  }
}

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

Secondly, for example 2, you can use else if to clear the nested structure


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

Now, it’s obvious that the version using the if statement is more readable and logical (by removing nesting).

However, the fact is not so. In addition to using ternary operators to express process control, a more common and widely used expression is as follows:

const val = expr ? trueValue : falseValue

const func = (age) => age > 18 ? ' Adults':'minors'

Similar to the above, using a short conditional expression to determine the value of a variable is quite common in development. In this case, the intention of ternary operator is clearer and its readability is higher than that of if statement, especially with anonymous function (lambda expression), which can greatly simplify our code.

The solution of Python is to support the above simplified version of ternary expression, and the expression does not support nesting, so as to achieve the purpose of developing strengths and avoiding weaknesses. However, the cost is that the implementation of the compiler will be complicated.

For golang, a simple compiler that can complete ast construction only through a single pass scan is one of the secrets of its rapid construction speed. It is unacceptable to increase the complexity of compiler implementation for such a simple function. At the same time, because of golang’s philosophy of “great road to simplicity”, the problems that can be solved with the existing grammatical structure will not add new grammar.

However, there are still ways, although not recommended:

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

  return b
}

age := 20
Val: = if (age > 18, "adult", "minor"). (string)

There are several reasons why this is not recommended

  1. Performance degradation due to interface usage
  2. Type assertion to be enforced
  3. No matter ternary expression or if statement, the branch that will not arrive will not be evaluated, that is, inert calculation; When you pass parameters to a function, every expression is evaluated

Finally, it is summarized as follows

Advantages of ternary operators:

  • For short expressions, it’s clearer to use ternary operators, especially after getting used to reading linear ternary operator expressions
  • No intermediate state is needed (for example, the let variable in the first example can be replaced with const, so the code is more robust), and the mental burden is lower
  • No intermediate state means less or no side effects, and code is easier to track and maintain

However, ternary operators also have obvious disadvantages

  • The readability of complex logic code is poor (for example, the status in the first example needs further condition judgment in the position of truevalue)
  • It is easy to be abused. Many people use it to replace if statements or simplify complex if nesting, which will lead to the result described in the previous article
  • Conditional branch can only be an expression, multiple statements are not supported

So this is a matter of different opinions. In short, we can only do as the Romans do.

reference resources

https://juejin.im/post/6844903561759850510

https://www.it-swarm.dev/zh/javascript/ Replace the nested ternary operator in JS / 1055944752/

https://golang.org/doc/faq#Does_Go_have_a_ternary_form

summary

Here is the article about why there is no ternary operator in golang. For more information about why there is no ternary operator in golang, please search previous articles of developer or continue to browse the following articles. I hope you can support developer more in the future!