After being tortured for 13 years, how does Go solve the reassignment pit?

Hello everyone, I am fried fish.

When looking at some historical proposals of Go recently, I found that there are some very magical proposals, which have been proposed for many years, but they are still not closed today, 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 ", @Rob Pike, the father of the Go language, directly stated that he wanted to kill := this way of reassignment, instead of tinkering and adding A bunch will 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/blo… If you are learning Go language, you can see the Go learning map and route . Welcome to Star to urge you to update.

Recommended reading

Guess you like

Origin juejin.im/post/7099302524607266829