Como Adiar (defer) a Execução de Funções na Linguagem Golang

in #golang6 years ago

As linhas de código em Golang são normalmente executadas em sequência, na ordem em que são escritas. Mas será que há alguma maneira de adiar a chamada de uma certa função?

A resposta é sim, usando a palavra-chave defer. Vamos aprender o conceito de adiar uma chamada de função com um exemplo. No código abaixo, temos duas linhas (dentro do corpo da função main) que imprimem texto ao console.

func main() {
  fmt.Println("Oi")
  fmt.Println("Tudo bem?")
}

A ordem de execução dos comandos é como escrita, então esperamos ver o seguinte no terminal:

Oi
Tudo bem?

Agora, o que será que acontece quando introduzimos a palavra-chave defer antes da chamada da primeira linha do corpo de main:

func main() {
  defer fmt.Println("Oi")
  fmt.Println("Tudo bem?")
}

Aqui está a saída do código acima:

Tudo bem?
Oi

Note que a segunda linha foi executada antes da primeira. Mas o que aconteceu? Bem, a palavra-chave defer faz a chamada da função que segue ser adiada.

Em mais detalhes, há uma stack de chamadas. Essa pilha armazena todas as chamadas que foram adiadas usando defer. Se tivermos três chamadas para o defer, como o seguinte:

defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")

Então as três chamadas serão adicionadas a pilha de chamadas, na seguinte ordem, do topo para o fundo:

// topo da stack
fmt.Println("3")
fmt.Println("2")
fmt.Println("1")
// fundo da stack

Quando chegar no final do corpo da função main(), os comandos armazenados nessa stack serão executados, começando do topo da stack.

Então a primeira chamada a ser adiada na verdade será a última a ser executada;

A última chamada a ser adiada será a primeira a ser executada.

Isso segue o conceito de last-in-first-out (LIFO): a última entrada é a primeira saída.

Para concluir, no último exemplo veremos a seguinte saída:

3
2
1

Para aprender mais sobre o defer, assista às aulas do NBK Mundo Tech:

Sort:  

Obrigado por postar! Esse comentário é o novo bot que dará upvote 5% para todos os posts que usam a tag #pt. Ainda não votou em mim como witness? Clique aqui e dê o seu voto! É rápido!