Hello everyone, I am fried fish.
Recently, when I was looking at some historical proposals of Go, I found that there are some very magical proposals, which have been proposed for many years, but they are still not closed, and people are constantly discussing them, but they cannot be solved.
There is a kind of "very angry and can't kill me", and today I will take everyone to see what it is.
background
The Go proposal " proposal: spec: various changes to := " introduced in this article today is a classic among classics, and it is a common problem for beginners to learn.
The proposal has been around since 2009, and was most recently discussed vigorously in 2021:
The code prototype is as follows:
func f() (err os.Error) {
v, err := g()
if err != nil {
return
}
if v {
v, err := h()
if err != nil {
return
}
}
}
The problem with this code is that the := in the if statement results in a new err variable, which causes the return parameter to be overwritten.
That is, the logic of := reassignment in Go will cause parameters to be overwritten, causing hidden problems.
new proposal
As mentioned at the beginning, this is a proposal that has not ended in 2022 after 13 years.
Summarizing the entire proposal and other ideas, we have put forward the following solutions or ideas:
- Add syntactic sugar.
- Get rid of grammar.
- set specifications.
add syntactic sugar
The idea removes the redeclaration := syntax and adds new : and :: syntax for new variable declarations.
The following code:
package bar
func foo() {
var x, err = f()
...
// 这里 “:err” 表示上面声明的 err。
var y, z, :err = g()
...
{
// 实际上,:err 表示代码区块里的已经声明的 err。
var w, :err = h()
...
// ::err 表示包级别声明的 err。
var u, v, ::err = j()
...
// 这个“err”是一个新的声明。
var m, n, err = k()
...
}
}
Three cases are given in the above code, namely:
- var :err = x: indicates the err declared in the most recent scope. The original meaning refers to the err declared above, so you will find different results in the code block and outside.
- var ::err = x: represents the err declared at the package level.
- var err = x: Indicates a new declaration.
kill grammar
In another proposal " proposal: Go 2: let := support any l-value that = supports ", the father of the Go language @
Rob Pike directly stated that he wanted to get rid of the := method of reassignment, instead of tinkering and adding a bunch of them would be more complicated.
As shown below:
I think we should aim to eliminate redeclaration, if we can build a smoother error handling model then redeclaration becomes less noticeable. But that won't happen anytime soon.
Remove features instead of adding them.
(shouting: less is more)
Multiple declarations on a single line
First modify the semantics of reassignment, all identifiers to the left of := are always declared as new variables, redeclaration within the same block is not allowed.
The following code:
a, err := foo()
b, err := foo() // 编译错误,因为 var err 已在此块中声明
The first line declaration is normal, the second line is redeclared in the same code block, so there will be a compilation error because it has already been declared.
Then add syntactic features that allow mixing = and := on a single line. The following code:
// a 和 err 被声明和初始化(相当于:a, err := foo()
a:=, err:= foo()
// b 被声明和初始化,而 err 只被赋予了一个新值
b:=, err= foo()
if true {
// c 在 if 块中声明并初始化,并为 err 分配一个新值
c:=, err= foo()
}
if true {
// d 和 err 在 if 块中声明,err 被隐藏
d:=, err:= foo()
}
Allowing multiple declarations on a single line essentially clarifies the scope of the declaration and increases the complexity of code readability.
Summarize
Today's article introduces you to a pit that was discovered 13 years ago (2009). When I first learned Go, I also encountered many tutorials and documents. Students would encounter this pit of reassignment statement.
In fact, the above three schemes seem to complement this redeclared syntactic sugar from different angles, but also increase the complexity.
Maybe just kill it, maybe it's a good choice?
The article is continuously updated, you can read it on WeChat by searching [Brain Fried Fish]. This article has been included in GitHub github.com/eddycjy/blog . To learn Go language, you can see the Go learning map and route . Welcome to Star to urge you to update.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。