Exporté vs Non-exporté
Fait partie de la section Logique & Flux du Journey GO de Coddy — leçon 52 sur 68.
En Go, la visibilité des identifiants (variables, fonctions, types, etc.) est contrôlée par une convention de nommage simple. Cela détermine si le code d'autres packages peut accéder à vos identifiants.
Les identifiants exportés commencent par une lettre majuscule et sont accessibles depuis d'autres packages. Considérez-les comme « publics » - ils peuvent être utilisés par quiconque importe votre package.
// Ceux-ci sont exportés (publics)
var Name string
func Calculate() int
type Person structLes identifiants non exportés commencent par une lettre minuscule et ne sont accessibles qu'au sein du même package. Ceux-ci sont « privés » à votre package.
// Ces éléments ne sont pas exportés (privés)
var age int
func helper() string
type config structCette convention de nommage est la manière dont Go contrôle l'accès sans avoir besoin de mots-clés comme public ou private. Lorsque vous essayez d'utiliser un identifiant non exporté depuis un autre package, Go vous donnera une erreur de compilation car cet identifiant n'est pas visible en dehors de son package.
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Défi
FacileCorrigez les problèmes de visibilité dans un package Go en rectifiant la convention de nommage pour les identifiants exportés et non exportés. Vous travaillerez sur un scénario simulé multi-packages où certains identifiants sont mal nommés, provoquant des erreurs de compilation lors de l'accès depuis d'autres packages.
Vous recevrez deux entrées :
- Une chaîne contenant les définitions de packages au format
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"(par exemple,"utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Une chaîne contenant les tentatives d'accès au format
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"(par exemple,"main.helper,main.Calculate,utils.Version")
Votre tâche consiste à :
- Analyser la première entrée en la découpant selon les barres verticales (pipes) pour obtenir les définitions individuelles des packages
- Pour chaque définition de package, découper selon les deux-points pour obtenir le nom du package et ses identifiants
- Pour chaque définition d'identifiant, découper selon les deux-points pour obtenir le nom de l'identifiant, son type et la visibilité prévue
- Créer une fonction nommée
fixIdentifierNamequi prend un nom d'identifiant et une visibilité prévue, et retourne le nom corrigé :- Si la visibilité est
"public", assurez-vous que l'identifiant commence par une lettre majuscule - Si la visibilité est
"private", assurez-vous que l'identifiant commence par une lettre minuscule
- Si la visibilité est
- Afficher l'en-tête de l'analyse des packages :
"=== PACKAGE VISIBILITY ANALYSIS ===" - Pour chaque package, afficher les informations du package :
"Package: [package_name]"- Pour chaque identifiant du package :
- Si le nom de l'identifiant doit être corrigé :
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - Si le nom de l'identifiant est correct :
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- Si le nom de l'identifiant doit être corrigé :
- Analyser la deuxième entrée en la découpant selon les virgules pour obtenir les tentatives d'accès individuelles
- Pour chaque tentative d'accès, découper selon les points pour obtenir le package accédant et l'identifiant accédé
- Afficher l'en-tête de validation des accès :
"=== ACCESS VALIDATION ===" - Pour chaque tentative d'accès, déterminer si l'accès est valide :
- Trouver le package qui contient l'identifiant
- Vérifier si le nom de l'identifiant corrigé commence par une lettre majuscule (exporté)
- Si l'identifiant est exporté :
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - Si l'identifiant n'est pas exporté :
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - Si l'identifiant n'existe pas :
"[accessing_package] accessing [target_package].[identifier_name]: ✗ NOT FOUND"
- Compter et afficher les statistiques de synthèse :
"=== 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]"
- Afficher les recommandations finales :
- S'il y avait des identifiants nécessitant des corrections :
"Recommendation: Fix identifier naming to follow Go conventions" - Si tous les identifiants étaient corrects :
"All identifiers follow proper Go naming conventions"
- S'il y avait des identifiants nécessitant des corrections :
Utilisez le package strings pour découper les chaînes d'entrée, le package fmt pour la sortie formatée, et les fonctions de manipulation de chaînes pour vérifier et modifier les noms d'identifiants. Ce défi démontre comment la convention de nommage de Go contrôle la visibilité des packages et vous aide à comprendre la différence entre les identifiants exportés et non exportés.
Aide-mémoire
Go contrôle la visibilité via des conventions de nommage sans mots-clés explicites comme public ou private.
Les identifiants exportés commencent par une lettre majuscule et sont accessibles depuis d'autres packages :
// Ceux-ci sont exportés (publics)
var Name string
func Calculate() int
type Person structLes identifiants non exportés commencent par une lettre minuscule et ne sont accessibles qu'au sein du même package :
// Ceux-ci ne sont pas exportés (privés)
var age int
func helper() string
type config structTenter d'accéder à des identifiants non exportés depuis d'autres packages entraîne des erreurs de compilation.
Essayez vous-même
package main
import (
"fmt"
"strings"
)
func main() {
// Lire l'entrée
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Écrivez votre code ci-dessous
// Créer la fonction fixIdentifierName
// Analyser les définitions de paquets
// Afficher l'analyse des paquets
// Analyser les tentatives d'accès
// Afficher la validation des accès
// Calculer et afficher les statistiques récapitulatives
// Afficher les recommandations
}Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Logique & Flux
1Structures de contrôle avancées
Switch avec `fallthrough`Sortir de boucles imbriquéesContinuer une boucle spécifiqueL'instruction `goto`Récapitulatif - Contrôle de boucle avancé4Projet : Liste de tâches simple
Configuration du projetAjouter une tâche2Structures et Méthodes
Définir des méthodes sur des structuresReceveurs par valeurReceveurs par pointeurChoisir les receveursMéthodes vs FonctionsRécapitulatif - Comportement des structures5Les Maps en profondeur
Maps de StructsPointeurs comme valeurs de MapTester les Maps NilComparer des MapsRécapitulatif - Compteur de fréquence de mots3Interfaces (Les bases)
Qu'est-ce qu'une Interface ?Définir une InterfaceImplémenter une InterfaceUtiliser les types d'InterfaceInterface videAssertions de typeType SwitchRécapitulatif - Formes et comportements6Go idiomatique : Les ensembles
L'idiome des ensembles en GoCréer un ensembleAjouter à un ensembleVérifier l'appartenanceSupprimer d'un ensembleItérer sur un ensembleRécapitulatif - Noms d'utilisateur uniques9Packages et Portée
Qu'est-ce qu'un Package ?Exporté vs Non-exportéCréer un Package SimpleAliasing de PackageL'identificateur blanc `_`La fonction `init`Récapitulatif - Créer un utilitaire