Exportiert vs. Nicht-exportiert
Teil des Abschnitts Logik & Ablauf der GO-Journey von Coddy. Lektion 52 von 68.
In Go wird die Sichtbarkeit von Bezeichnern (Variablen, Funktionen, Typen usw.) durch eine einfache Namenskonvention geregelt. Sie bestimmt, ob Code aus anderen Paketen auf deine Bezeichner zugreifen kann.
Exportierte Bezeichner beginnen mit einem Großbuchstaben und sind aus anderen Paketen zugänglich. Betrachte sie als „öffentlich“ – sie können von allen verwendet werden, die dein Paket importieren.
// Diese sind exportiert (öffentlich)
var Name string
func Calculate() int
type Person structNicht exportierte Bezeichner beginnen mit einem Kleinbuchstaben und sind nur innerhalb desselben Pakets zugänglich. Sie sind „privat“ für dein Paket.
// Diese sind nicht exportiert (privat)
var age int
func helper() string
type config structDiese Namenskonvention ist Gos Art, den Zugriff zu steuern, ohne Schlüsselwörter wie public oder private zu benötigen. Wenn du versuchst, einen nicht exportierten Bezeichner aus einem anderen Paket zu verwenden, gibt Go einen Kompilierungsfehler aus, weil dieser Bezeichner außerhalb seines Pakets nicht sichtbar ist.
Aufgabe
EinfachBehebe Sichtbarkeitsprobleme in einem Go-Paket, indem du die Namenskonvention für exportierte und nicht exportierte Bezeichner korrigierst. Du arbeitest mit einem simulierten Szenario mit mehreren Paketen, in dem einige Bezeichner falsch benannt sind und dadurch Kompilierungsfehler verursachen, wenn von anderen Paketen aus auf sie zugegriffen wird.
Du erhältst zwei Eingaben:
- Eine Zeichenkette mit Paketdefinitionen im Format
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"(z. B."utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Eine Zeichenkette mit Zugriffsversuchen im Format
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"(z. B."main.helper,main.Calculate,utils.Version")
Deine Aufgabe ist es:
- Die erste Eingabe zu analysieren, indem du sie an Pipes aufteilst, um die einzelnen Paketdefinitionen zu erhalten
- Jede Paketdefinition an Doppelpunkten aufzuteilen, um den Paketnamen und seine Bezeichner zu erhalten
- Jede Bezeichnerdefinition an Doppelpunkten aufzuteilen, um den Bezeichnernamen, den Typ und die vorgesehene Sichtbarkeit zu erhalten
- Eine Funktion namens
fixIdentifierNamezu erstellen, die einen Bezeichnernamen und die vorgesehene Sichtbarkeit entgegennimmt und den korrigierten Namen zurückgibt:- Wenn die Sichtbarkeit
"public"ist, stelle sicher, dass der Bezeichner mit einem Großbuchstaben beginnt - Wenn die Sichtbarkeit
"private"ist, stelle sicher, dass der Bezeichner mit einem Kleinbuchstaben beginnt
- Wenn die Sichtbarkeit
- Die Kopfzeile der Paketanalyse auszugeben:
"=== PACKAGE VISIBILITY ANALYSIS ===" - Für jedes Paket die Paketinformationen auszugeben:
"Package: [package_name]"- Für jeden Bezeichner im Paket:
- Wenn der Bezeichnername korrigiert werden muss:
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - Wenn der Bezeichnername korrekt ist:
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- Wenn der Bezeichnername korrigiert werden muss:
- Die zweite Eingabe an Kommas aufzuteilen, um die einzelnen Zugriffsversuche zu erhalten
- Jeden Zugriffsversuch an Punkten aufzuteilen, um das zugreifende Paket und den Bezeichner, auf den zugegriffen wird, zu erhalten
- Die Kopfzeile der Zugriffsvalidierung auszugeben:
"=== ACCESS VALIDATION ===" - Für jeden Zugriffsversuch festzustellen, ob der Zugriff gültig ist:
- Das Paket zu finden, das den Bezeichner enthält
- Zu prüfen, ob der korrigierte Bezeichnername mit einem Großbuchstaben beginnt (exportiert)
- Wenn der Bezeichner exportiert ist:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - Wenn der Bezeichner nicht exportiert ist:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - Wenn der Bezeichner nicht existiert:
"[accessing_package] accessing unknown.[identifier_name]: ✗ NOT FOUND"(gib das Wortunknownals Paket aus; dieser Versuch zählt als verweigerter Zugriff)
- Die zusammenfassenden Statistiken zu zählen und auszugeben:
"=== 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]"
- Die abschließenden Empfehlungen auszugeben:
- Wenn Bezeichner korrigiert werden mussten:
"Recommendation: Fix identifier naming to follow Go conventions" - Wenn alle Bezeichner korrekt waren:
"All identifiers follow proper Go naming conventions"
- Wenn Bezeichner korrigiert werden mussten:
Verwende das Paket strings, um die Eingabezeichenketten aufzuteilen, das Paket fmt für die formatierte Ausgabe und Zeichenkettenfunktionen, um Bezeichnernamen zu prüfen und zu ändern. Diese Herausforderung zeigt, wie die Namenskonvention von Go die Paketsichtbarkeit steuert, und hilft dir, den Unterschied zwischen exportierten und nicht exportierten Bezeichnern zu verstehen.
Probier es selbst
package main
import (
"fmt"
"strings"
)
func main() {
// Eingabe einlesen
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Schreibe deinen Code unten
// Die Funktion fixIdentifierName erstellen
// Paketdefinitionen parsen
// Paketanalyse anzeigen
// Zugriffsversuche parsen
// Zugriffsvalidierung anzeigen
// Zusammenfassende Statistiken berechnen und anzeigen
// Empfehlungen anzeigen
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik & Ablauf
1Fortgeschrittener Kontrollfluss
Switch mit `fallthrough`Abbrechen von verschachtelten SchleifenFortsetzen einer bestimmten SchleifeDie `goto`-AnweisungZusammenfassung – Fortgeschrittene Schleifensteuerung4Projekt: Einfache Aufgabenliste
Projekt-SetupEine Aufgabe hinzufügen2Structs und Methoden
Methoden für Structs definierenValue ReceiverPointer ReceiverReceiver auswählenMethoden vs. FunktionenZusammenfassung – Struct-Verhalten5Maps im Detail
Maps von StructsPointer als Map-WertePrüfen auf Nil-MapsMaps vergleichenZusammenfassung – Wortfrequenz-Zähler8Projekt: Einfache Bestandsverwaltung
ProjektübersichtLagerbestand prüfen11Abschlussherausforderungen
Einfache KontaktlisteEinfacher Zahlen-ValidatorSammler für eindeutige Elemente3Interfaces (Die Grundlagen)
Was ist ein Interface?Ein Interface definierenEin Interface implementierenInterface-Typen verwendenLeeres InterfaceType AssertionsType SwitchZusammenfassung – Formen und Verhalten6Idiomatisches Go: Sets
Das Set-Idiom in GoEin Set erstellenElemente zu einem Set hinzufügenPrüfen auf MitgliedschaftAus einem Set entfernenÜber ein Set iterierenZusammenfassung – Eindeutige Benutzernamen9Packages und Scope
Was ist ein Package?Exportiert vs. Nicht-exportiertEin einfaches Package erstellenPackage-AliasingDer Blank Identifier `_`Die `init`-FunktionRecap – Erstellen eines UtilitysÜbe selbstständig: Online-Go-Compiler