Hello everyone, I am fried fish.
Goto statement is often criticized in community discussions, thinking that it destroys structured programming and program abstraction, is harmful and terrible.
The earliest point of view comes from Edsger Dijkstra's letter " Go To Statement Considered Harmful " in 1968, expressing the idea that it is harmful.
As shown below:
But, but, actually...
Go supports the goto statement, but many people don't understand it. The Go Team that shouted "less is more" actually added it...
Today, I will show you by Fried Fish.
Goto syntax
The syntax format of Goto is as follows:
goto label
...
...
label: statement
The code example is as follows:
package main
import "fmt"
func main() {
learnGoTo()
}
func learnGoTo() {
fmt.Println("a")
goto FINISH
fmt.Println("b")
FINISH:
fmt.Println("c")
}
The above code first outputs a in the function learnGoTo
, and then reaches the goto FINISH
code segment, so it jumps directly to the output of c, so the output code of b is skipped directly.
Output result:
a
c
Dangers of Goto
A classic name for the dangers of Goto is: Spaghetti code , a derogatory term for unstructured and hard-to-maintain source code.
Such code has complex and tangled control structures, resulting in program flow that is conceptually like a bowl of spaghetti, twisted and tangled.
The reference code is as follows:
INPUT "How many numbers should be sorted? "; T
DIM n(T)
FOR i = 1 TO T
PRINT "NUMBER:"; i
INPUT n(i)
NEXT i
'Calculations:
C = T
E180:
C = INT(C / 2)
IF C = 0 THEN GOTO C330
D = T - C
E = 1
I220:
f = E
F230:
g = f + C
IF n(f) > n(g) THEN SWAP n(f), n(g)
f = f - C
IF f > 0 THEN GOTO F230
E = E + 1
IF E > D THEN GOTO E180
GOTO I220
C330:
PRINT "The sorted list is"
FOR i = 1 TO T
PRINT n(i)
NEXT i
In the above example, you can see that the goto statement can flow around in any control flow , and you may have to remember what its label is and where to jump to.
Programmers also have to come up with various names, such as: Fried Fish Brother, Fried Fish Younger Brother, Fried Fish Friend. The inspiration for the name is poor and it's easy to get confused.
For long-term business code in the real world, the abuse of goto statements may be more serious.
The meaning of Goto's existence
Go Spec
In fact, in Go, the Goto statement has stricter restrictions than other languages, and its usage is explained in the Go Spec " Goto statements ".
The spec says that there can be no variable declarations etc. in the scope of the goto statement, which is a bad smell.
The following code:
goto L // BAD
v := 3
L:
Because this would cause the declaration of the variable v to be skipped.
At the same time, it is required that the goto statement outside the code block cannot jump to the label in another code block.
The following code:
if n%2 == 1 {
goto L1
}
for n > 0 {
f()
n--
L1:
f()
n--
}
You cannot cross scope from an if block to a for block.
Go standard library source code example
Take a look at the math/gamma.go source code in the Go standard library for a good example.
The following code:
for x < 0 {
if x > -1e-09 {
goto small
}
z = z / x
x = x + 1
}
for x < 2 {
if x < 1e-09 {
goto small
}
z = z / x
x = x + 1
}
if x == 2 {
return z
}
x = x - 2
p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
q = ((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x + _gamQ[7]
return z * p / q
small:
if x == 0 {
return Inf(1)
}
return z / ((1 + Euler*x) * x)
}
When observing the code from top to bottom, it is possible to identify the goto statement faster and see the label jump below, which is acceptable in terms of implementation and readability.
significance
Speaking of which, some students may find it. If there is a problem, it is more in the absence of restrictions. Of course, it is unreasonable for goto to fly around.
But there are actually two schools of thought, as the readers of our previous article mentioned:
You can blame programmers for writing spaghetti, or you can rely on language-level evasion. This can be done better, and every new programmer does not need to re-cultivate awareness.
Go also supports label jumping in break, which is similar to goto:
Loop:
for {
select {
...
break Loop
}
}
Go Team obviously chose the language level to avoid some of the complex scenarios of goto, restricting the goto jump to only one code block , so that it can have better readability and get corresponding value.
Summarize
The generation of a new keyword must contain its background reasons and behaviors. If you just blindly cut across the board, you will definitely solve the loneliness in the end.
After nearly 60 years of goto knowledge and thinking in the computer industry, everyone has realized that goto jumping around in arbitrary control flow is very disgusting. Including the world's best language PHP, in fact, since 5.3.0, goto has also been added carefully, and it is also limited, and the scope is the same file and scope.
The new goto form is an exploration of this restricted goto pattern. what do you think?
If you need to go to somewhere, goto is the way to go. - Ken Thompson
The article is updated continuously, you can read it by searching on WeChat [Brain fried fish]. This article has been included in GitHub github.com/eddycjy/blog . If you are learning Go language, you can see the Go learning map and route . Welcome to Star to urge you to update.
Go Book Series
- Introduction to the Go language series: a preliminary exploration of the actual combat of the Go project
- Go Programming Journey: Deep Dive into Go Projects
- Go Language Design Philosophy: Understanding Go Why and Design Thinking
- Go Language Advanced Tour: Go deeper into the Go source code
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。