Exportado vs. No exportado
Parte de la sección Lógica y Flujo del Journey de GO de Coddy. Lección 52 de 68.
En Go, la visibilidad de los identificadores (variables, funciones, tipos, etc.) se controla mediante una convención de nombres sencilla. Esto determina si el código de otros paquetes puede acceder a tus identificadores.
Los identificadores exportados empiezan con una letra mayúscula y son accesibles desde otros paquetes. Piensa en ellos como «públicos»: cualquiera que importe tu paquete puede usarlos.
// Estos se exportan (son públicos)
var Name string
func Calculate() int
type Person structLos identificadores no exportados empiezan con una letra minúscula y solo son accesibles dentro del mismo paquete. Son «privados» de tu paquete.
// Estos no se exportan (son privados)
var age int
func helper() string
type config structEsta convención de nombres es la forma que tiene Go de controlar el acceso sin necesitar palabras clave como public o private. Cuando intentas usar un identificador no exportado de otro paquete, Go te dará un error de compilación porque ese identificador no es visible fuera de su paquete.
Desafío
FácilCorrige los problemas de visibilidad en un paquete de Go arreglando las convenciones de nomenclatura de los identificadores exportados y no exportados. Trabajarás con un escenario simulado de varios paquetes en el que algunos identificadores tienen nombres incorrectos, lo que provoca errores de compilación cuando se accede a ellos desde otros paquetes.
Recibirás dos entradas:
- Una cadena que contiene definiciones de paquetes con el formato
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"(por ejemplo,"utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Una cadena que contiene intentos de acceso con el formato
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"(por ejemplo,"main.helper,main.Calculate,utils.Version")
Tu tarea es:
- Analizar la primera entrada separándola por barras verticales para obtener definiciones de paquetes individuales
- Para cada definición de paquete, separarla por dos puntos para obtener el nombre del paquete y sus identificadores
- Para cada definición de identificador, separarla por dos puntos para obtener el nombre del identificador, el tipo y la visibilidad prevista
- Crear una función llamada
fixIdentifierNameque reciba el nombre de un identificador y su visibilidad prevista, y devuelva el nombre corregido:- Si la visibilidad es
"public", asegúrate de que el identificador empiece con una letra mayúscula - Si la visibilidad es
"private", asegúrate de que el identificador empiece con una letra minúscula
- Si la visibilidad es
- Mostrar el encabezado del análisis de paquetes:
"=== PACKAGE VISIBILITY ANALYSIS ===" - Para cada paquete, mostrar la información del paquete:
"Package: [package_name]"- Para cada identificador del paquete:
- Si hay que corregir el nombre del identificador:
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - Si el nombre del identificador es correcto:
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- Si hay que corregir el nombre del identificador:
- Analizar la segunda entrada separándola por comas para obtener intentos de acceso individuales
- Para cada intento de acceso, separarlo por puntos para obtener el paquete que realiza el acceso y el identificador al que se accede
- Mostrar el encabezado de validación de acceso:
"=== ACCESS VALIDATION ===" - Para cada intento de acceso, determinar si el acceso es válido:
- Encontrar el paquete que contiene el identificador
- Comprobar si el nombre corregido del identificador empieza con una letra mayúscula (exportado)
- Si el identificador está exportado:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - Si el identificador no está exportado:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - Si el identificador no existe:
"[accessing_package] accessing unknown.[identifier_name]: ✗ NOT FOUND"(imprimir la palabraunknowncomo paquete; este intento cuenta como un acceso denegado)
- Contar y mostrar las estadísticas del resumen:
"=== 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]"
- Mostrar las recomendaciones finales:
- Si había identificadores que necesitaban corrección:
"Recommendation: Fix identifier naming to follow Go conventions" - Si todos los identificadores eran correctos:
"All identifiers follow proper Go naming conventions"
- Si había identificadores que necesitaban corrección:
Usa el paquete strings para separar las cadenas de entrada, el paquete fmt para dar formato a la salida y funciones de manipulación de cadenas para comprobar y modificar los nombres de los identificadores. Este desafío demuestra cómo las convenciones de nomenclatura de Go controlan la visibilidad de los paquetes y te ayuda a comprender la diferencia entre identificadores exportados y no exportados.
Pruébalo tú mismo
package main
import (
"fmt"
"strings"
)
func main() {
// Lee la entrada
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Escribe tu código a continuación
// Crea la función fixIdentifierName
// Analiza las definiciones de paquetes
// Muestra el análisis de paquetes
// Analiza los intentos de acceso
// Muestra la validación de acceso
// Calcula y muestra las estadísticas resumidas
// Muestra las recomendaciones
}Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Lógica y Flujo
1Flujo de control avanzado
Switch con `fallthrough`Salir de bucles anidadosContinuar un bucle específicoLa sentencia `goto`Repaso: Control de bucles avanzado4Proyecto: Lista de tareas sencilla
Configuración del proyectoAñadir una tarea2Estructuras y Métodos
Definición de métodos en estructurasReceptores de valorReceptores de punteroElegir receptoresMétodos vs FuncionesResumen - Comportamiento de estructuras5Mapas en profundidad
Mapas de StructsPunteros como valores de MapVerificación de Maps NilComparación de MapsResumen - Contador de frecuencia de palabras3Interfaces (Conceptos básicos)
¿Qué es una interfaz?Definir una interfazImplementar una interfazUso de tipos de interfazInterfaz vacíaAserciones de tipoType SwitchResumen: Formas y comportamientos6Go idiomático: Sets
El modismo de Set en GoCrear un SetAñadir a un SetComprobar pertenenciaEliminar de un SetIterar sobre un SetResumen: Nombres de usuario únicos9Paquetes y Ámbito
¿Qué es un paquete?Exportado vs. No exportadoCrear un paquete simpleAlias de paquetesEl identificador en blanco `_`La función `init`Repaso - Construir una utilidadPractica por tu cuenta: Compilador de Go online