Eksportowane a nieeksportowane
Część sekcji Logika i przepływ sterowania ścieżki GO w Coddy. Lekcja 52 z 68.
W Go widoczność identyfikatorów (zmiennych, funkcji, typów itp.) jest określana przez prostą konwencję nazewniczą. Decyduje ona o tym, czy kod z innych pakietów może uzyskać dostęp do Twoich identyfikatorów.
Eksportowane identyfikatory zaczynają się wielką literą i są dostępne z innych pakietów. Możesz myśleć o nich jak o „publicznych” — może ich używać każdy, kto zaimportuje Twój pakiet.
// Te są eksportowane (publiczne)
var Name string
func Calculate() int
type Person structNieeksportowane identyfikatory zaczynają się małą literą i są dostępne tylko w obrębie tego samego pakietu. Są „prywatne” dla Twojego pakietu.
// Te są nieeksportowane (prywatne)
var age int
func helper() string
type config structTa konwencja nazewnictwa to sposób języka Go na kontrolowanie dostępu bez potrzeby używania słów kluczowych takich jak public czy private. Gdy spróbujesz użyć nieeksportowanego identyfikatora z innego pakietu, Go zgłosi błąd kompilacji, ponieważ ten identyfikator nie jest widoczny poza swoim pakietem.
Wyzwanie
ŁatwyNapraw problemy z widocznością w pakiecie Go, korygując konwencję nazewnictwa identyfikatorów eksportowanych i nieeksportowanych. Będziesz pracować z symulowanym scenariuszem obejmującym wiele pakietów, w którym niektóre identyfikatory mają nieprawidłowe nazwy, co powoduje błędy kompilacji przy odwoływaniu się do nich z innych pakietów.
Otrzymasz dwa wejścia:
- Łańcuch zawierający definicje pakietów w formacie
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"(np."utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Łańcuch zawierający próby dostępu w formacie
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"(np."main.helper,main.Calculate,utils.Version")
Twoim zadaniem jest:
- Przeanalizować pierwsze wejście, dzieląc je według pionowych kresek, aby uzyskać poszczególne definicje pakietów
- Dla każdej definicji pakietu podzielić ją według dwukropków, aby uzyskać nazwę pakietu i jego identyfikatory
- Dla każdej definicji identyfikatora podzielić ją według dwukropków, aby uzyskać nazwę identyfikatora, typ i zamierzoną widoczność
- Utworzyć funkcję o nazwie
fixIdentifierName, która przyjmuje nazwę identyfikatora i zamierzoną widoczność oraz zwraca skorygowaną nazwę:- Jeśli widoczność to
"public", upewnić się, że identyfikator zaczyna się wielką literą - Jeśli widoczność to
"private", upewnić się, że identyfikator zaczyna się małą literą
- Jeśli widoczność to
- Wyświetlić nagłówek analizy pakietów:
"=== PACKAGE VISIBILITY ANALYSIS ===" - Dla każdego pakietu wyświetlić informacje o pakiecie:
"Package: [package_name]"- Dla każdego identyfikatora w pakiecie:
- Jeśli nazwa identyfikatora wymaga poprawy:
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - Jeśli nazwa identyfikatora jest poprawna:
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- Jeśli nazwa identyfikatora wymaga poprawy:
- Przeanalizować drugie wejście, dzieląc je według przecinków, aby uzyskać poszczególne próby dostępu
- Dla każdej próby dostępu podzielić ją według kropek, aby uzyskać pakiet uzyskujący dostęp i identyfikator, do którego uzyskuje dostęp
- Wyświetlić nagłówek walidacji dostępu:
"=== ACCESS VALIDATION ===" - Dla każdej próby dostępu ustalić, czy dostęp jest prawidłowy:
- Odnaleźć pakiet zawierający identyfikator
- Sprawdzić, czy skorygowana nazwa identyfikatora zaczyna się wielką literą (eksportowany)
- Jeśli identyfikator jest eksportowany:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - Jeśli identyfikator nie jest eksportowany:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - Jeśli identyfikator nie istnieje:
"[accessing_package] accessing [target_package].[identifier_name]: ✗ NOT FOUND"
- Policzyć i wyświetlić statystyki podsumowujące:
"=== 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]"
- Wyświetlić końcowe zalecenia:
- Jeśli były identyfikatory wymagające poprawy:
"Recommendation: Fix identifier naming to follow Go conventions" - Jeśli wszystkie identyfikatory były poprawne:
"All identifiers follow proper Go naming conventions"
- Jeśli były identyfikatory wymagające poprawy:
Użyj pakietu strings do dzielenia łańcuchów wejściowych, pakietu fmt do formatowania danych wyjściowych oraz funkcji manipulujących łańcuchami do sprawdzania i modyfikowania nazw identyfikatorów. To wyzwanie pokazuje, jak konwencja nazewnictwa w Go kontroluje widoczność pakietów i pomaga zrozumieć różnicę między identyfikatorami eksportowanymi i nieeksportowanymi.
Spróbuj swoich sił
package main
import (
"fmt"
"strings"
)
func main() {
// Wczytaj dane wejściowe
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Napisz swój kod poniżej
// Utwórz funkcję fixIdentifierName
// Przeanalizuj definicje pakietów
// Wyświetl analizę pakietów
// Przeanalizuj próby dostępu
// Wyświetl wyniki weryfikacji dostępu
// Oblicz i wyświetl statystyki podsumowujące
// Wyświetl zalecenia
}Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Zaawansowane sterowanie przepływem
Instrukcja switch z `fallthrough`Przerywanie zagnieżdżonych pętliKontynuowanie określonej pętliInstrukcja `goto`Podsumowanie — zaawansowane sterowanie pętlami4Projekt: Prosta lista zadań
Konfiguracja projektuDodawanie zadania2Struktury i metody
Definiowanie metod dla strukturOdbiorniki przez wartośćOdbiorniki przez wskaźnikWybór odbiornikówMetody a funkcjePodsumowanie — działanie struktur5Mapy w szczegółach
Mapy strukturWskaźniki jako wartości mapSprawdzanie, czy mapy są nilPorównywanie mapPodsumowanie — licznik częstości słów3Interfejsy (podstawy)
Czym jest interfejs?Definiowanie interfejsuImplementowanie interfejsuUżywanie typów interfejsowychPusty interfejsAsercje typuPrzełącznik typówPodsumowanie – kształty i zachowania6Idiomatyczny Go: zbiory
Idiom zbioru w GoTworzenie zbioruDodawanie elementów do zbioruSprawdzanie przynależnościUsuwanie elementów ze zbioruIterowanie po zbiorzePodsumowanie – unikalne nazwy użytkowników9Pakiety i zakres
Czym jest pakiet?Eksportowane a nieeksportowaneTworzenie prostego pakietuAliasy pakietówIdentyfikator pusty `_`Funkcja `init`Podsumowanie — tworzenie narzędziaPoćwicz samodzielnie: Kompilator Go online