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 toute personne qui 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 sont accessibles uniquement au sein du même package. Ils sont « privés » dans 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 paquet, Go vous indiquera une erreur de compilation, car cet identifiant n’est pas visible en dehors de son paquet.
Défi
FacileCorrigez les problèmes de visibilité dans un package Go en corrigeant la convention de nommage des identifiants exportés et non exportés. Vous travaillerez avec un scénario simulé impliquant plusieurs packages, dans lequel certains identifiants sont nommés incorrectement, ce qui provoque des erreurs de compilation lorsqu’ils sont utilisés depuis d’autres packages.
Vous recevrez deux entrées :
- Une chaîne contenant les définitions des 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 séparant sur les barres verticales afin d’obtenir les définitions individuelles des packages
- Pour chaque définition de package, la séparer sur les deux-points afin d’obtenir le nom du package et ses identifiants
- Pour chaque définition d’identifiant, la séparer sur les deux-points afin d’obtenir le nom de l’identifiant, son type et sa visibilité prévue
- Créer une fonction appelée
fixIdentifierNamequi prend un nom d’identifiant et une visibilité prévue, et renvoie le nom corrigé :- Si la visibilité est
"public", vérifier que l’identifiant commence par une lettre majuscule - Si la visibilité est
"private", vérifier 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 séparant sur les virgules afin d’obtenir les tentatives d’accès individuelles
- Pour chaque tentative d’accès, la séparer sur les points afin d’obtenir le package qui effectue l’accès et l’identifiant ciblé
- 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 corrigé de l’identifiant 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 récapitulatives :
"=== 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 séparer les chaînes d’entrée, le package fmt pour produire une sortie formatée, ainsi que des fonctions de manipulation des chaînes pour vérifier et modifier les noms des identifiants. Ce défi montre comment la convention de nommage de Go contrôle la visibilité au niveau des packages et vous aide à comprendre la différence entre les identifiants exportés et non exportés.
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 utilitaireEntraînez-vous par vous-même : Compilateur Go en ligne