Interfaces, interface {}, conversions
Une interface dans Go spécifie unensemble de méthodes. Tout type qui implémente cet ensemble de méthodes est ditimplémenter l'interface.
Une interface est implémentée implicitement. Il n'y a pasmet en oeuvremot-clé, utilisé dans d'autres langues. Si un type définit l'ensemble de méthodes d'une interface, il l'implémente. C'est ce qu'on appelle le typage structurel, l'équivalent à la compilation defrappe de canard.
S'il marche comme un canard, nage comme un canard et charlatan comme un canard, c'est un canard
Important: dans Go, l'interface abstraite un ensemble de méthodes (actions), pas de données.
Exemple
L'exemple suivant tiré deComment utiliser les interfaces dans Goillustre une interface de base d'un animal qui peut parler, et différentes structures qui satisfont l'interface:
type Animal interface {
Speak() string
}
type Dog struct {
}
func (d Dog) Speak() string {
return “Woof!”
}
type Cat struct {
}
func (c Cat) Speak() string {
return “Meow!”
}
type Llama struct {
}
func (l Llama) Speak() string {
return “???”
}
type JavaProgrammer struct {
}
func (j JavaProgrammer) Speak() string {
return “Design patterns!”
}
Vous pouvez construire un [] animal et courirSpeak()
sur son contenu:
func main() {
animals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
}
L'interface vide
LeAnimal
L'interface est petite et agréable, mais il y a quelque chose d'encore plus simple, mais un concept un peu complexe à comprendre pour les débutants: l'interface vide.
interface{}
est l'interface Go empty, un concept clé. Chaque type l'implémente par définition.
Une interface est un type, vous pouvez donc définir par exemple:
type Dog struct {
Age interface{}
}
et vous pouvez également passer un type d'interface vide comme paramètre de fonction:
func Eat(t interface{}) {
// ...
}
Acceptantinterface{}
ne signifie pas que la fonction accepte n'importe quel type, mais signifie plutôt que Eat accepte une valeur deinterface{}
taper.
Au moment de l'exécution, Go convertira la valeur réelle transmise en uninterface{}
évaluer.
Si vous définissez un champ dans une structure de typeinterface{}
, vous pouvez lui attribuer une valeur de n'importe quel type. Par exemple:
package main
import “fmt”
type Dog struct {
Age interface{}
}
func main() {
dog := Dog{}
dog.Age = “3”
fmt.Printf("%#v %T\n", dog.Age, dog.Age)
<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span> = <span style="color:#ae81ff">3</span>
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"%#v %T\n"</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>)
<span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span> = <span style="color:#e6db74">"not really an age"</span>
<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">"%#v %T"</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>, <span style="color:#a6e22e">dog</span>.<span style="color:#a6e22e">Age</span>)
}
impressions
"3" string
3 int
"not really an age" string
Bien sûr, cela ne se limite pas aux types de base: vous pouvez y stocker une tranche, une carte, n'importe quelle structure personnalisée.
Comment l'interface est représentée en interne
En interne, une interfaceévaluerc'est deuxwords
, ensembles d'octets.
Un mot pointe vers la valeur du type sous-jacent. Un mot pointe vers les données.
Les conversions
Quand nous avons faitanimals := []Animal{Dog{}, Cat{}, Llama{}, JavaProgrammer{}}
auparavant, Go convertissait automatiquement tous nos types d'animaux spécifiques en un type d'animal. Chaque élément de cette tranche est maintenant de type Animal, le type sous-jacent pointant vers les espèces spécifiques, comme le chien, le chat et le lama.
Mais si une méthode accepte[]interface{}
par exemple, nous ne pouvons pas simplement passeranimals
à lui, car le type ne correspond pas. Nous devons le faireconvertir explicitement chaqueAnimal
à uninterface{}
avant, avec une boucle, comme décrit dans lePuis-je convertir un [] T en une [] interface {}FAQ:
t := []int{1, 2, 3, 4}
s := make([]interface{}, len(t))
for i, v := range t {
s[i] = v
}
Déterminez le type sous-jacent d'uninterface{}
Si une valeur est de typeinterface{}
, vous souhaiterez peut-être déterminer le type sous-jacent. Comment? Avec un interrupteur sur.(type)
, aimerGo efficaceexplique:
Un commutateur peut également être utilisé pour découvrir le type dynamique d'une variable d'interface. Un tel commutateur de type utilise la syntaxe d'une assertion de type avec le type de mot-clé entre parenthèses. Si le commutateur déclare une variable dans l'expression, la variable aura le type correspondant dans chaque clause. Il est également idiomatique de réutiliser le nom dans de tels cas, en déclarant en fait une nouvelle variable avec le même nom mais un type différent dans chaque cas.
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
Plus de tutoriels go:
- Utilisation du proxy inverse NGINX pour servir les services Go
- Faire une copie d'une structure dans Go
- Les bases d'un serveur Web Go
- Trier un type de carte dans Go
- Allez les pointeurs en un mot
- Go Tags expliqué
- Aller au formatage de la date et de l'heure
- Traitement JSON avec Go
- Fonctions Go Variadic
- Fiche de triche Go Strings
- L'interface Go Empty expliquée
- Débogage Go avec VS Code et Delve
- Named Go renvoie des paramètres
- Générer des nombres et des chaînes aléatoires dans Go
- Structure du système de fichiers d'un projet Go
- Algorithme de recherche binaire implémenté dans Go
- Utilisation des indicateurs de ligne de commande dans Go
- GOPATH a expliqué
- Créez une application de ligne de commande avec Go: lolcat
- Création d'une commande CLI avec Go: cowsay
- Utilisation de Shell Pipes avec Go
- Tutoriel Go CLI: Clone de fortune
- Lister les fichiers dans un dossier avec Go
- Utilisez Go pour obtenir une liste des référentiels à partir de GitHub
- Allez, ajoutez une tranche de chaînes à un fichier
- Allez, convertissez une chaîne en une tranche d'octets
- Visualisez vos contributions Git locales avec Go
- Premiers pas avec Go CPU et profilage de la mémoire
- Résolution de l'erreur "ne prend pas en charge l'indexation" dans un programme Go
- Mesure du temps d'exécution dans un programme Go
- Création d'un robot d'exploration Web avec Go pour détecter les titres en double
- Go Best Practices: pointeur ou récepteurs de valeur?
- Go Best Practices: Devez-vous utiliser une méthode ou une fonction?
- Go Structures de données: définir
- Aide-mémoire Go Maps
- Générer des implémentations pour les types génériques dans Go
- Go Data Structures: Dictionnaire
- Structures de données Go: table de hachage
- Implémenter des écouteurs d'événements dans Passer par les canaux
- Go Structures de données: pile
- Go Structures de données: file d'attente
- Go Structures de données: arbre de recherche binaire
- Go Structures de données: graphique
- Structures de données Go: liste liée
- Le guide complet des structures de données Go
- Comparaison des valeurs Go
- Est-ce que Go est orienté objet?
- Travailler avec une base de données SQL dans Go
- Utilisation des variables d'environnement dans Go
- Tutoriel Go: API REST soutenue par PostgreSQL
- Activation de CORS sur un serveur Web Go
- Déployer une application Go dans un conteneur Docker
- Pourquoi Go est un langage puissant à apprendre en tant que développeur PHP
- Allez, supprimez le caractère de nouvelle ligne io.Reader.ReadString
- Allez, comment observer les changements et reconstruire votre programme
- Allez, comptez les mois depuis une date
- Accéder aux paramètres HTTP POST dans Go