Depois de ser torturado por 13 anos, como Go resolve o poço de reatribuição?

Olá a todos, eu sou peixe frito.

Ao olhar para algumas propostas históricas do Go recentemente, descobri que existem algumas propostas muito mágicas, que foram propostas por muitos anos, mas ainda não estão fechadas hoje, e as pessoas estão constantemente discutindo, mas não podem ser resolvidas.

Existe uma espécie de "muito bravo e não pode me matar", e hoje vou levar todo mundo para ver o que é.

fundo

A proposta Go " proposta: spec: várias mudanças para := " apresentada neste artigo hoje é um clássico entre os clássicos, e é um problema comum para iniciantes aprenderem.

A proposta existe desde 2009 e foi mais recentemente discutida vigorosamente em 2021:

O protótipo do código é o seguinte:

func f() (err os.Error) {
	v, err := g()
	if err != nil {
		return
	}
	if v {
		v, err := h()
		if err != nil {
			return
		}
	}
}
复制代码

O problema com esse código é que o := na instrução if resulta em uma nova variável err, que faz com que o parâmetro de retorno seja substituído.

Ou seja, a lógica de := reatribuição em Go fará com que os parâmetros sejam sobrescritos, causando problemas ocultos.

Nova proposta

Como mencionado no início, esta é uma proposta que não terminou em 2022 após 13 anos.

Resumindo toda a proposta e outras ideias, apresentamos as seguintes soluções ou ideias:

  • Adicione o açúcar sintático.
  • Livre-se da gramática.
  • definir especificações.

adicionar açúcar sintático

A ideia remove a sintaxe de redeclaration := e adiciona novas sintaxes : e :: para novas declarações de variáveis.

O seguinte código:

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()
   	...
   }
}
复制代码

Três casos são dados no código acima, a saber:

  • var :err = x: indica o erro declarado no escopo mais recente, e o significado original refere-se ao erro declarado acima, então você encontrará resultados diferentes no bloco de código e fora dele.
  • var ::err = x: representa o erro declarado no nível do pacote.
  • var err = x: Indica uma nova declaração.

matar gramática

Em outra proposta " proposta: Go 2: deixe := suportar qualquer l-value que = suporte ", @Rob Pike, o pai da linguagem Go, afirmou diretamente que queria matar := essa forma de reatribuição, em vez de mexer e adicionar um monte será mais complicado.

Como mostrado abaixo:

Acho que devemos ter como objetivo eliminar a redeclaração, se pudermos construir um modelo de tratamento de erros mais suave, a redeclaração se tornará menos perceptível. Mas isso não vai acontecer tão cedo.

Remova recursos em vez de adicioná-los.

(gritando: menos é mais)

Várias declarações em uma única linha

Primeiro modifique a semântica da reatribuição, todos os identificadores à esquerda de := são sempre declarados como novas variáveis, a redeclaração dentro do mesmo bloco não é permitida.

O seguinte código:

a, err := foo()
b, err := foo() // 编译错误,因为 var err 已在此块中声明
复制代码

A declaração da primeira linha é normal, a segunda linha é redeclarada no mesmo bloco de código, então haverá um erro de compilação porque já foi declarado.

Em seguida, adicione recursos sintáticos que permitem misturar = e := em uma única linha. O seguinte código:

// 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()
}
复制代码

Permitir várias declarações em uma única linha essencialmente esclarece o escopo da declaração e aumenta a complexidade da legibilidade do código.

Resumir

O artigo de hoje apresenta um poço que foi descoberto há 13 anos (2009). Quando aprendi Go, também encontrei muitos tutoriais e documentos.Os alunos se deparavam com esse poço de declaração de reatribuição.

De fato, os três esquemas acima parecem complementar esse açúcar sintático redeclarado de diferentes ângulos, mas também aumentam a complexidade.

Talvez apenas mate, talvez seja uma boa escolha?

O artigo é atualizado continuamente, você pode lê-lo no WeChat pesquisando por [Brain Fried Fish]. Este artigo foi incluído no GitHub github.com/eddycjy/blo… Se você está aprendendo a linguagem Go, você pode ver o mapa de aprendizagem Go e rota . Bem-vindo ao Star para incentivá-lo a atualizar.

Leitura recomendada

Acho que você gosta

Origin juejin.im/post/7099302524607266829
Recomendado
Clasificación