Go did not have a logical operator for short-circuit evaluation

I didn't pay much attention to it, but I stumbled, so I made a note. Since the package and import statements are omitted, please check the link for the complete code.

The Go version of the code below is go1.14.9.

TL;DR ** Go does not have a logical operator for non-short-circuit evaluation, so if you include a function **

-** Evaluate in advance or ** -** Function should be written on the left side **

Stumble point

Suppose you have code like this:

https://play.golang.org/p/en49-fRSNLU

func main() {
	funcCalled := true
	funcCalled = funcCalled || returnFalse()
	fmt.Println(funcCalled)
}

func returnFalse() bool {
	fmt.Println("returnFalse() called")
	return false
}
true

Program exited.

I wanted to call returnFalse () every time, but I never got " returnFalse () called ".

this is**||Is the short-circuit evaluation, and the left side istrueIn the case of, the right side is not evaluated and the process is completed.**is.

ThereforefuncCalled = funcCalled || returnFalse()Is

--For funcCalled: = true --The right-hand side returnFalse () is not evaluated and the process is completed.

solution

To call returnFalse (), it is generally

  1. ** Call the function in advance and evaluate it **
  2. funcCalled = returnFalse() || funcCalledWrite the function call first, like
  3. ** Use the logical operator | which is not short-circuit evaluation **

Modify to one of.

First, when the function is called and evaluated in advance.

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

func main() {
	funcCalled := true
	result := returnFalse() //Evaluation in advance
	funcCalled = result || funcCalled
	fmt.Println(funcCalled)
}

func returnFalse() bool {
	fmt.Println("returnFalse() called")
	return false
}

returnFalse() called
true

Program exited.

It's OK.

Next, when the function call of 2, is described first.

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

func main() {
	funcCalled := true
	funcCalled = returnFalse() || funcCalled //Write the function call first
	fmt.Println(funcCalled)
}

func returnFalse() bool {
	fmt.Println("returnFalse() called")
	return false
}
returnFalse() called
true

Program exited.

Looks good.

Finally, if you use the logical operator | which is not a short-circuit evaluation of 3.

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

func main() {
	funcCalled := true
	funcCalled = funcCalled | returnFalse() //Use operators that are not short-circuit evaluation
	fmt.Println(funcCalled)
}

func returnFalse() bool {
	fmt.Println("returnFalse() called")
	return false
}
./prog.go:9:26: invalid operation: funcCalled | returnFalse() (operator | not defined on bool)

Go build failed.

I got an error. Is it not defined?

Let's take a look at the language specifications.

https://golang.org/ref/spec#Logical_operators

Logical operators apply to boolean values and yield a result of the same type as the operands. The right operand is evaluated conditionally.

&&    conditional AND    p && q  is  "if p then q else false"
||    conditional OR     p || q  is  "if p then true else q"
!     NOT                !p      is  "not p"

It didn't seem to be defined.

Conclusion

** Go does not have a logical operator for non-short-circuit evaluation, so if you include a function **

-** Evaluate in advance or ** -** Function should be written on the left side **

Recommended Posts

Go did not have a logical operator for short-circuit evaluation