Exportado vs Não Exportado
Parte da seção Lógica & Fluxo do Journey de GO da Coddy. Lição 52 de 68.
Em Go, a visibilidade dos identificadores (variáveis, funções, tipos etc.) é controlada por uma convenção simples de nomenclatura. Isso determina se o código de outros pacotes pode acessar seus identificadores.
Identificadores exportados começam com uma letra maiúscula e podem ser acessados por outros pacotes. Pense neles como "públicos" — eles podem ser usados por qualquer pessoa que importe seu pacote.
// Estes são exportados (públicos)
var Name string
func Calculate() int
type Person structIdentificadores não exportados começam com uma letra minúscula e só podem ser acessados dentro do mesmo pacote. Eles são "privados" do seu pacote.
// Estes não são exportados (privados)
var age int
func helper() string
type config structEssa convenção de nomenclatura é a maneira do Go de controlar o acesso sem precisar de palavras-chave como public ou private. Quando você tenta usar um identificador não exportado de outro pacote, o Go gera um erro de compilação porque esse identificador não é visível fora do seu pacote.
Desafio
FácilCorrija os problemas de visibilidade em um pacote Go ajustando a convenção de nomenclatura para identificadores exportados e não exportados. Você trabalhará com um cenário simulado de vários pacotes, no qual alguns identificadores estão nomeados incorretamente, causando erros de compilação quando são acessados de outros pacotes.
Você receberá duas entradas:
- Uma string contendo definições de pacotes no formato
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"(por exemplo,"utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Uma string contendo tentativas de acesso no formato
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"(por exemplo,"main.helper,main.Calculate,utils.Version")
Sua tarefa é:
- Analisar a primeira entrada dividindo-a por barras verticais para obter as definições individuais dos pacotes
- Para cada definição de pacote, dividir por dois-pontos para obter o nome do pacote e seus identificadores
- Para cada definição de identificador, dividir por dois-pontos para obter o nome do identificador, o tipo e a visibilidade pretendida
- Criar uma função chamada
fixIdentifierNameque recebe um nome de identificador e a visibilidade pretendida e retorna o nome corrigido:- Se a visibilidade for
"public", garantir que o identificador comece com uma letra maiúscula - Se a visibilidade for
"private", garantir que o identificador comece com uma letra minúscula
- Se a visibilidade for
- Exibir o cabeçalho da análise dos pacotes:
"=== PACKAGE VISIBILITY ANALYSIS ===" - Para cada pacote, exibir as informações do pacote:
"Package: [package_name]"- Para cada identificador no pacote:
- Se o nome do identificador precisar ser corrigido:
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - Se o nome do identificador estiver correto:
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- Se o nome do identificador precisar ser corrigido:
- Analisar a segunda entrada dividindo-a por vírgulas para obter as tentativas de acesso individuais
- Para cada tentativa de acesso, dividir por pontos para obter o pacote que está fazendo o acesso e o identificador acessado
- Exibir o cabeçalho da validação de acesso:
"=== ACCESS VALIDATION ===" - Para cada tentativa de acesso, determinar se o acesso é válido:
- Encontrar o pacote que contém o identificador
- Verificar se o nome corrigido do identificador começa com uma letra maiúscula (exportado)
- Se o identificador for exportado:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - Se o identificador não for exportado:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - Se o identificador não existir:
"[accessing_package] accessing unknown.[identifier_name]: ✗ NOT FOUND"(exibir a palavraunknowncomo o pacote; essa tentativa conta como um acesso negado)
- Contar e exibir as estatísticas resumidas:
"=== SUMMARY ===""Total packages analyzed: [number_of_packages]""Total identifiers processed: [total_number_of_identifiers]""Identifiers requiring fixes: [number_of_identifiers_that_needed_fixing]""Access attempts: [number_of_access_attempts]""Allowed accesses: [number_of_allowed_accesses]""Denied accesses: [number_of_denied_accesses]"
- Exibir as recomendações finais:
- Se houver identificadores que precisem de correção:
"Recommendation: Fix identifier naming to follow Go conventions" - Se todos os identificadores estiverem corretos:
"All identifiers follow proper Go naming conventions"
- Se houver identificadores que precisem de correção:
Use o pacote strings para dividir as strings de entrada, o pacote fmt para a saída formatada e funções de manipulação de strings para verificar e modificar os nomes dos identificadores. Este desafio demonstra como a convenção de nomenclatura do Go controla a visibilidade dos pacotes e ajuda você a entender a diferença entre identificadores exportados e não exportados.
Experimente você mesmo
package main
import (
"fmt"
"strings"
)
func main() {
// Leia a entrada
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Escreva seu código abaixo
// Crie a função fixIdentifierName
// Analise as definições de pacotes
// Exiba a análise dos pacotes
// Analise as tentativas de acesso
// Exiba a validação dos acessos
// Calcule e exiba as estatísticas resumidas
// Exiba as recomendações
}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 Comportamentos6Go Idiomático: Conjuntos
O Idioma de Conjuntos em GoCriando um ConjuntoAdicionando a um ConjuntoVerificando a Existência de ElementosRemovendo de um ConjuntoIterando sobre um ConjuntoRecapitulação - Nomes de Usuário Únicos9Pacotes e Escopo
O que é um Pacote?Exportado vs Não ExportadoCriando um Pacote SimplesAliasing de PacotesO Identificador em Branco `_` A função `init`Recapitulação - Construindo um UtilitárioPratique por conta própria: Compilador de Go online