Esportato e non esportato
Fa parte della sezione Logica e flusso del percorso GO di Coddy. Lezione 52 di 68.
In Go, la visibilità degli identificatori (variabili, funzioni, tipi, ecc.) è controllata da una semplice convenzione di denominazione. Questo determina se il codice di altri package può accedere ai tuoi identificatori.
Gli identificatori esportati iniziano con una lettera maiuscola e sono accessibili da altri pacchetti. Considerali «pubblici»: possono essere usati da chiunque importi il tuo pacchetto.
// Questi sono esportati (pubblici)
var Name string
func Calculate() int
type Person structGli identificatori non esportati iniziano con una lettera minuscola e sono accessibili solo all'interno dello stesso pacchetto. Sono "privati" del tuo pacchetto.
// Questi non sono esportati (privati)
var age int
func helper() string
type config structQuesta convenzione di denominazione è il modo in cui Go controlla l’accesso senza bisogno di parole chiave come public o private. Quando provi a usare un identificatore non esportato da un altro pacchetto, Go ti darà un errore di compilazione perché quell’identificatore non è visibile al di fuori del suo pacchetto.
Sfida
FacileCorreggi i problemi di visibilità in un package Go correggendo le convenzioni di denominazione per gli identificatori esportati e non esportati. Lavorerai con uno scenario simulato con più package, in cui alcuni identificatori hanno nomi non corretti e causano errori di compilazione quando vengono usati da altri package.
Riceverai due input:
- Una stringa contenente definizioni di package nel formato
"package_name:identifier1:type1:visibility1,identifier2:type2:visibility2|package_name:identifier1:type1:visibility1"(ad esempio,"utils:helper:function:private,Calculate:function:public|main:name:variable:private,Version:variable:public") - Una stringa contenente tentativi di accesso nel formato
"accessing_package.identifier1,accessing_package.identifier2,accessing_package.identifier3"(ad esempio,"main.helper,main.Calculate,utils.Version")
Il tuo compito è:
- Analizzare il primo input dividendolo in corrispondenza delle barre verticali per ottenere le singole definizioni dei package
- Per ogni definizione di package, dividerla in corrispondenza dei due punti per ottenere il nome del package e i suoi identificatori
- Per ogni definizione di identificatore, dividerla in corrispondenza dei due punti per ottenere il nome dell'identificatore, il tipo e la visibilità prevista
- Creare una funzione chiamata
fixIdentifierNameche accetta il nome di un identificatore e la visibilità prevista e restituisce il nome corretto:- Se la visibilità è
"public", assicurati che l'identificatore inizi con una lettera maiuscola - Se la visibilità è
"private", assicurati che l'identificatore inizi con una lettera minuscola
- Se la visibilità è
- Visualizzare l'intestazione dell'analisi dei package:
"=== PACKAGE VISIBILITY ANALYSIS ===" - Per ogni package, visualizzare le informazioni sul package:
"Package: [package_name]"- Per ogni identificatore nel package:
- Se il nome dell'identificatore deve essere corretto:
"- [original_name] ([type]) -> [corrected_name] (visibility: [visibility])" - Se il nome dell'identificatore è corretto:
"- [identifier_name] ([type]) (visibility: [visibility]) ✓"
- Se il nome dell'identificatore deve essere corretto:
- Analizzare il secondo input dividendolo in corrispondenza delle virgole per ottenere i singoli tentativi di accesso
- Per ogni tentativo di accesso, dividerlo in corrispondenza dei punti per ottenere il package che effettua l'accesso e l'identificatore a cui si accede
- Visualizzare l'intestazione della convalida degli accessi:
"=== ACCESS VALIDATION ===" - Per ogni tentativo di accesso, determinare se l'accesso è valido:
- Trovare il package che contiene l'identificatore
- Verificare se il nome corretto dell'identificatore inizia con una lettera maiuscola (esportato)
- Se l'identificatore è esportato:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✓ ALLOWED (exported)" - Se l'identificatore non è esportato:
"[accessing_package] accessing [target_package].[corrected_identifier_name]: ✗ DENIED (unexported)" - Se l'identificatore non esiste:
"[accessing_package] accessing [target_package].[identifier_name]: ✗ NOT FOUND"
- Contare e visualizzare le statistiche riepilogative:
"=== 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]"
- Visualizzare le raccomandazioni finali:
- Se ci sono identificatori da correggere:
"Recommendation: Fix identifier naming to follow Go conventions" - Se tutti gli identificatori sono corretti:
"All identifiers follow proper Go naming conventions"
- Se ci sono identificatori da correggere:
Usa il package strings per suddividere le stringhe di input, il package fmt per l'output formattato e le funzioni di manipolazione delle stringhe per controllare e modificare i nomi degli identificatori. Questa sfida mostra come le convenzioni di denominazione di Go controllino la visibilità dei package e ti aiuta a comprendere la differenza tra identificatori esportati e non esportati.
Provalo tu
package main
import (
"fmt"
"strings"
)
func main() {
// Leggi l'input
var packageDefinitions string
var accessAttempts string
fmt.Scanln(&packageDefinitions)
fmt.Scanln(&accessAttempts)
// TODO: Scrivi il tuo codice qui sotto
// Crea la funzione fixIdentifierName
// Analizza le definizioni dei package
// Mostra l'analisi dei package
// Analizza i tentativi di accesso
// Mostra la convalida degli accessi
// Calcola e mostra le statistiche riepilogative
// Mostra le raccomandazioni
}Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Logica e flusso
1Flusso di controllo avanzato
Switch con `fallthrough`Uscire dai cicli annidatiContinuare un ciclo specificoL'istruzione `goto`Riepilogo - Controllo avanzato dei cicli4Progetto: semplice lista di attività
Configurazione del progettoAggiungere un’attività2Struct e metodi
Definire metodi sugli structReceiver per valoreReceiver con puntatoreScegliere i receiverMetodi vs funzioniRiepilogo - comportamento degli struct5Mappe in dettaglio
Mappe di structPuntatori come valori delle mappeVerificare le mappe nilConfrontare le mappeRiepilogo - Contatore della frequenza delle parole3Interfacce (le basi)
Che cos’è un’interfaccia?Definire un’interfacciaImplementare un’interfacciaUsare i tipi interfacciaInterfaccia vuotaAsserzioni di tipoSwitch di tipoRiepilogo: forme e comportamenti6Gli insiemi in Go idiomatico
L'idioma degli insiemi in GoCreare un insiemeAggiungere elementi a un insiemeVerificare l'appartenenzaRimuovere elementi da un insiemeIterare su un insiemeRiepilogo - Nomi utente univoci9Pacchetti e ambito
Che cos’è un pacchetto?Esportato e non esportatoCreare un pacchetto sempliceAlias dei pacchettiL’identificatore vuoto `_`La funzione `init`Riepilogo: creare un’utilitàEsercitati da solo: Compilatore Go online