Interfaccia vuota (any)
Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 28 di 107.
La interfaccia vuota è un'interfaccia con zero metodi. Poiché ogni tipo in Go ha almeno zero metodi, ogni tipo soddisfa automaticamente l'interfaccia vuota. Questo le permette di contenere valori di qualsiasi tipo.
var anything interface{}
anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}A partire da Go 1.18, la parola chiave any è stata introdotta come alias di interface{}. Sono completamente intercambiabili, ma any è più semplice da leggere.
var value any = "Go is awesome"L’interfaccia vuota è utile quando devi gestire valori di tipo sconosciuto o variabile. Funzioni come fmt.Println la usano per accettare argomenti di qualsiasi tipo:
func PrintAnything(v any) {
fmt.Println("Value:", v)
}
func main() {
PrintAnything(100)
PrintAnything("text")
PrintAnything(3.14)
}Tuttavia, c'è un compromesso. Quando un valore viene memorizzato in un'interfaccia vuota, perdi l'accesso alle informazioni sul suo tipo specifico.
Non puoi chiamare direttamente i metodi né accedere ai campi senza prima estrarre il tipo sottostante. Nelle prossime lezioni vedrai come recuperare il tipo concreto da un'interfaccia vuota usando asserzioni di tipo e switch di tipo.
Sfida
FacileCostruiamo un contenitore di archiviazione flessibile, in grado di contenere valori di qualsiasi tipo usando l’interfaccia vuota. Creerai una semplice scatola che mostra come any ti permette di memorizzare tipi diversi nella stessa struttura.
Organizzerai il codice in due file:
box.go: definisci una structBoxcon un unico campoContentdi tipoany. Crea una funzione costruttriceNewBoxche accetta un valore di qualsiasi tipo e restituisce un puntatore a una Box contenente quel valore. Aggiungi un metodoDescribeche restituisce una stringa che mostra cosa è memorizzato nella scatola.main.go: leggi valori diversi dall’input, crea scatole contenenti un intero, una stringa e un booleano, poi stampa la descrizione di ogni scatola per mostrare come lo stesso tipo Box possa contenere valori completamente diversi.
Verranno forniti i seguenti input:
- Riga 1: un valore intero
- Riga 2: un valore stringa
- Riga 3: un valore booleano (
trueofalse)
Il tuo metodo Describe dovrebbe restituire una stringa in questo formato:
Box contains: [value]Ad esempio, dati 42, hello e true, l’output dovrebbe essere:
Box contains: 42
Box contains: hello
Box contains: trueL’intuizione fondamentale è che la tua singola struct Box può memorizzare un intero, una stringa o un booleano: tutto grazie al fatto che il tipo any accetta valori di qualsiasi tipo. Ogni scatola contiene qualcosa di diverso, eppure sono tutte dello stesso tipo Box.
Provalo tu
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// Leggi il valore intero
line1, _ := reader.ReadString('\n')
intVal, _ := strconv.Atoi(strings.TrimSpace(line1))
// Leggi il valore stringa
line2, _ := reader.ReadString('\n')
strVal := strings.TrimSpace(line2)
// Leggi il valore booleano
line3, _ := reader.ReadString('\n')
boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))
// TODO: Crea un box per ogni valore usando NewBox
// TODO: Stampa la descrizione di ogni box usando il metodo Describe
// Usa le variabili per evitare errori di compilazione (rimuovi queste righe durante l'implementazione)
_ = intVal
_ = strVal
_ = boolVal
// Esempio di formato dell'output:
// fmt.Println(box.Describe())
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti di OOP in Go
File esterniWorkspace e moduli GoPacchetti e importazioniNomi esportati e non esportatiIntroduzione all’OOP in GoGli struct come classiDefinire metodi sugli structReceiver con puntatore vs receiver con valoreInizializzazione degli structFunzioni costruttriciRiepilogo - Calcolatrice semplice4Interfacce
Introduzione alle interfacceImplementazione implicitaL’interfaccia come contrattoInterfaccia vuota (any)Asserzione di tipoSwitch sul tipoComposizione di interfacceInterfacce Stringer ed ErrorRipasso - Calcolatore di forme7Incapsulamento
Campi esportati e non esportatiIncapsulamento a livello di packageMetodi Getter e SetterNascondimento delle informazioni in GoRiepilogo - Registri degli studenti10Tipi generici (Go 1.18+)
Introduzione ai tipi genericiParametri di tipoVincoli di tipoStruct genericheSoluzione alternativa per i metodi genericiRiepilogo - Collezione generica13Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneModello SingletonModello FactoryModello Abstract FactoryModello ObserverModello Strategy2Approfondimento su tipi e struct
Tipi di base e compostiDefinizioni di tipi personalizzatiTag delle structStruct anonimeStruct annidateValori zero e predefinitiRipasso - Rubrica5Composizione invece dell'ereditarietà
Perché Go non ha l'ereditarietàFondamenti dell'embedding delle structPromozione dei metodiEmbedding di più structEmbedding e aggregazione a confrontoMascheramento dei metodi embeddedRiepilogo: gerarchia dei dipendenti8Gestione degli errori e OOP
L'interfaccia errorTipi di errore personalizzatiWrapping degli errori (fmt.Errorf)Errori sentinellaerrors.Is() ed errors.As()Panic, Defer e RecoverRiepilogo - Parser di file11Libreria standard e OOP
io.Reader e io.Writersort.InterfaceInterfaccia fmt.Stringerencoding/json con le structInterfaccia http.HandlerRipasso - modelli REST API14Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositeMiddleware come Decorator3Puntatori e memoria
Concetti base dei puntatori in GoPuntatori a structPassaggio per valore vs per riferimentoLa funzione new()Garbage collection in GoRiepilogo - Costruttore di liste concatenate6Polimorfismo in Go
Polimorfismo tramite interfacceDuck typing in GoRegole di soddisfacimento delle interfacceCollezioni polimorficheIniezione delle dipendenzeRiepilogo - Elaboratore di pagamenti9Concorrenza e OOP
Basi delle goroutineCanali e comunicazioneCanali bufferizzati vs non bufferizzatiIstruzione selectsync.Mutex e sync.RWMutexsync.WaitGroupProgettazione di struct thread-safeRiepilogo: worker poolEsercitati da solo: Compilatore Go online