A função `init`
Parte da seção Lógica & Fluxo do Journey de GO da Coddy. Lição 56 de 68.
A função init é uma função especial em Go que é executada automaticamente quando um pacote é importado. Ao contrário de funções regulares, você não chama init diretamente - o Go a executa para você durante o processo de inicialização do pacote.
Veja como você define uma função init:
package mypackage
import "fmt"
func init() {
fmt.Println("Package mypackage is being initialized!")
}A função init possui algumas características únicas: ela não recebe parâmetros, não retorna valores e é executada antes do início da função main. Isso a torna perfeita para configurar o estado inicial, registrar componentes ou realizar tarefas de configuração única que seu pacote necessita.
Quando você importa um pacote que contém uma função init, você verá seus efeitos imediatamente, mesmo que não use nenhuma das funções exportadas do pacote. É por isso que o padrão de importação com identificador em branco que você aprendeu anteriormente é tão útil - ele permite disparar a inicialização de um pacote sem usar seu código diretamente.
Desafio
FácilCrie um sistema de inicialização de pacotes que demonstre como as funções init são executadas automaticamente quando os pacotes são importados. Você criará um sistema de registro no qual diferentes pacotes inicializam a si mesmos e rastreiam sua sequência de inicialização.
Você receberá duas entradas:
- Uma string contendo definições de pacotes no formato
"package1:message1,package2:message2,package3:message3"(por exemplo,"database:Database connection pool initialized,cache:Cache system ready,logger:Logging system started") - Uma string contendo as operações do programa principal no formato
"operation1,operation2,operation3"(por exemplo,"start_server,process_requests,shutdown")
Sua tarefa é:
- Analisar a primeira entrada dividindo-a nas vírgulas para obter as definições individuais dos pacotes
- Para cada definição de pacote, dividi-la nos dois-pontos para obter o nome do pacote e a mensagem de inicialização
- Criar uma fatia global chamada
initLogpara rastrear as mensagens de inicialização - Criar uma função chamada
logInitque receba um nome de pacote e uma mensagem e, em seguida, adicione a mensagem formatada"[INIT] [package_name]: [message]"à fatiainitLog - Simular a inicialização dos pacotes chamando
logInitpara cada pacote na ordem em que aparecem na entrada - Exibir o cabeçalho da sequência de inicialização:
"=== PACKAGE INITIALIZATION SEQUENCE ===" - Imprimir cada mensagem de inicialização da fatia
initLog - Exibir o cabeçalho do programa principal:
"=== MAIN PROGRAM EXECUTION ===" - Imprimir:
"All packages initialized successfully" - Analisar a segunda entrada dividindo-a nas vírgulas para obter as operações individuais
- Para cada operação no programa principal:
- Imprimir:
"Executing: [operation]" - Adicionar uma mensagem ao registro:
"[MAIN] Operation: [operation]" - Exibir o resumo da execução:
"=== EXECUTION SUMMARY ===""Packages initialized: [number_of_packages]""Main operations executed: [number_of_operations]""Total log entries: [total_number_of_log_entries]"- Exibir o registro completo:
"=== COMPLETE EXECUTION LOG ==="- Imprimir cada entrada do registro completo (tanto as mensagens de inicialização quanto as operações principais)
- Exibir a mensagem final:
"Program execution completed - all init functions ran before main"
Use o pacote strings para dividir as strings de entrada e o pacote fmt para a saída formatada. Este desafio demonstra como as funções init são executadas automaticamente durante a importação de pacotes e sempre são executadas antes da função main, o que as torna perfeitas para tarefas de configuração e inicialização de pacotes.
Experimente você mesmo
package main
import (
"bufio"
"fmt"
"os"
"strings"
)
// Slice global para rastrear mensagens de inicialização
var initLog []string
func main() {
reader := bufio.NewReader(os.Stdin)
// Lê a entrada (bufio lida corretamente com linhas com espaços)
packageDefs, _ := reader.ReadString('\n')
packageDefs = strings.TrimRight(packageDefs, "\r\n")
mainOps, _ := reader.ReadString('\n')
mainOps = strings.TrimRight(mainOps, "\r\n")
// TODO: Escreva seu código abaixo
// 1. Analise packageDefs dividindo por "," para obter entradas de pacotes individuais
// 2. Para cada entrada, divida por ":" (máximo 2 partes) para obter packageName e message
// 3. Crie uma função logInit(packageName, message string) que anexa
// "[INIT] [packageName]: message" ao slice global initLog
// 4. Exiba o cabeçalho da sequência de inicialização e todas as entradas de log de inicialização
// 5. Exiba o cabeçalho de execução principal e processe cada operação de mainOps
// - Imprima "Executing: <op>" para cada operação
// - Anexe "[MAIN] Operation: <op>" ao initLog
// 6. Exiba o resumo da execução (contagem de pacotes, contagem de operações, total de entradas de log)
// 7. Exiba o log completo e a mensagem final de conclusão
}Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica & Fluxo
1Fluxo de Controle Avançado
Switch com `fallthrough`Interrompendo Loops AninhadosContinuando um Loop EspecíficoA Instrução `goto`Recapitulação - Controle de Loop Avançado4Projeto: Lista de Tarefas Simples
Configuração do ProjetoAdicionando uma Tarefa2Structs e Métodos
Definindo Métodos em StructsRecebedores de ValorRecebedores de PonteiroEscolhendo RecebedoresMétodos vs FunçõesRecapitulação - Comportamento de Structs5Mapas em Profundidade
Mapas de StructsPonteiros como Valores de MapVerificando Mapas NilComparando MapasRecapitulação - Contador de Frequência de Palavras3Interfaces (O Básico)
O que é uma Interface?Definindo uma InterfaceImplementando uma InterfaceUsando Tipos de InterfaceInterface VaziaAsserções de TipoType SwitchRecapitulação - Formas e ComportamentosPratique por conta própria: Compilador de Go online