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, etc.) durch eine einfache Namenskonvention gesteuert. Dies bestimmt, ob Code aus anderen Paketen auf Ihre Bezeichner zugreifen kann.
Exportierte Bezeichner beginnen mit einem Großbuchstaben und sind von anderen Paketen aus zugänglich. Betrachten Sie sie als „öffentlich“ – sie können von jedem verwendet werden, der Ihr Paket importiert.
// 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. Diese sind für Ihr Paket „privat“.
// Diese sind nicht exportiert (privat)
var age int
func helper() string
type config structDiese Namenskonvention ist Gos Methode, den Zugriff zu steuern, ohne Schlüsselwörter wie public oder private zu benötigen. Wenn Sie versuchen, einen nicht exportierten Bezeichner aus einem anderen Paket zu verwenden, wird Go einen Kompilierungsfehler ausgeben, da dieser Bezeichner außerhalb seines Pakets nicht sichtbar ist.
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Aufgabe
EinfachBeheben Sie die Sichtbarkeitsprobleme in einem Go-Paket, indem Sie die Namenskonvention für exportierte und nicht exportierte Bezeichner korrigieren. Sie arbeiten mit einem simulierten Multi-Paket-Szenario, in dem einige Bezeichner falsch benannt sind, was zu Kompilierungsfehlern führt, wenn von anderen Paketen darauf zugegriffen wird.
Sie erhalten zwei Eingaben:
- Einen String, der Paketdefinitionen im Format
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"enthält (z. B."utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Einen String, der Zugriffsversuche im Format
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"enthält (z. B."main.helper,main.Calculate,utils.Version")
Ihre Aufgabe ist es:
- Die erste Eingabe zu parsen, indem Sie sie an den Pipes aufteilen, um einzelne Paketdefinitionen zu erhalten
- Für jede Paketdefinition die Doppelpunkte aufzuteilen, um den Paketnamen und seine Bezeichner zu erhalten
- Für jede Bezeichnerdefinition die Doppelpunkte aufzuteilen, um den Bezeichnernamen, den Typ und die beabsichtigte Sichtbarkeit zu erhalten
- Eine Funktion namens
fixIdentifierNamezu erstellen, die einen Bezeichnernamen und die beabsichtigte Sichtbarkeit entgegennimmt und den korrigierten Namen zurückgibt:- Wenn die Sichtbarkeit
"public"ist, stellen Sie sicher, dass der Bezeichner mit einem Großbuchstaben beginnt - Wenn die Sichtbarkeit
"private"ist, stellen Sie sicher, dass der Bezeichner mit einem Kleinbuchstaben beginnt
- Wenn die Sichtbarkeit
- Den Header für die Paketanalyse anzuzeigen:
"=== PACKAGE VISIBILITY ANALYSIS ===" - Für jedes Paket die Paketinformationen anzuzeigen:
"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 zu parsen, indem Sie sie an den Kommas aufteilen, um einzelne Zugriffsversuche zu erhalten
- Für jeden Zugriffsversuch die Punkte aufzuteilen, um das zugreifende Paket und den Bezeichner, auf den zugegriffen wird, zu erhalten
- Den Header für die Zugriffsvalidierung anzuzeigen:
"=== ACCESS VALIDATION ===" - Für jeden Zugriffsversuch zu bestimmen, ob der Zugriff gültig ist:
- Finden Sie das Paket, das den Bezeichner enthält
- Prüfen Sie, 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 [target_package].[identifier_name]: ✗ NOT FOUND"
- Die Zusammenfassungsstatistik zu zählen und anzuzeigen:
"=== 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 anzuzeigen:
- Wenn es Bezeichner gab, die Korrekturen erforderten:
"Recommendation: Fix identifier naming to follow Go conventions" - Wenn alle Bezeichner korrekt waren:
"All identifiers follow proper Go naming conventions"
- Wenn es Bezeichner gab, die Korrekturen erforderten:
Verwenden Sie das strings-Paket, um die Eingabestrings aufzuteilen, das fmt-Paket für die formatierte Ausgabe und String-Manipulationsfunktionen, um Bezeichnernamen zu prüfen und zu ändern. Diese Herausforderung zeigt, wie die Namenskonvention von Go die Paketsichtbarkeit steuert, und hilft Ihnen, den Unterschied zwischen exportierten und nicht exportierten Bezeichnern zu verstehen.
Spickzettel
Go steuert die Sichtbarkeit durch Namenskonventionen ohne explizite Schlüsselwörter wie public oder private.
Exportierte Bezeichner beginnen mit einem Großbuchstaben und sind von anderen Paketen aus zugänglich:
// 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:
// Diese sind nicht exportiert (privat)
var age int
func helper() string
type config structDer Versuch, auf nicht exportierte Bezeichner aus anderen Paketen zuzugreifen, führt zu Kompilierungsfehlern.
Probier es selbst
package main
import (
"fmt"
"strings"
)
func main() {
// Eingabe lesen
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Schreiben Sie Ihren Code unten
// Erstellen Sie die Funktion fixIdentifierName
// Paketdefinitionen parsen
// Paket-Analyse 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