Golang 20 : Les interfaces(Part II)
Les interfaces(Part II)
La représentation interne d'une interface
Une interface est intérieurement représentée par un tuple (type, value)
. type
est le type implicite concret de l'interface et value
contient la valeur du type concret.
On va écrire un programme pour mieux comprendre les choses.
package main
import (
"fmt"
)
type Test interface {
Tester()
}
type MyFloat float64
func (m MyFloat) Tester() {
fmt.Println(m)
}
func describe(t Test) {
fmt.Printf("Type d'interface %T valeur %v\n", t, t)
}
func main() {
var t Test
f := MyFloat(89.7)
t = f
describe(t)
t.Tester()
}
Test interface à une seule méthode Tester()
et le type MyFloat implémente cette interface. On attribue la variable f
de type MyFloat
à t
qui est de type Test
. Maintenant le type concret de t est Myfloat
et la valeur de t est 89.7
. La fonction describe
affiche la valeur et le type concret de l'interface. La sortie du programme est:
Type d'interface main.Myfloat valeur 89.7
89.7
Interface vide
Une interface qui n'a pas de méthodes est appelée interface vide interface{}
. Puisque l'interface vide n'a aucune méthode, tous les types peuvent implémenter l'interface vide.
package main
import (
"fmt"
)
func describe(i interface{}) {
fmt.Printf("Type = %T, value = %v\n", i, i)
}
func main() {
s := "Hello World"
describe(s)
i := 55
describe(i)
strt := struct {
name string
}{
name: "Naveen R",
}
describe(strt)
}
Dans le programme ci-dessus, la fonction describe(i interface{})
prend comme argument l'interface vide, par conséquent on peut lui passer n'importe quel type.
On a passé une chaîne de caractères, un entier et une structure à la fonction describe
. Le programme affiche:
Type = string, value = Hello World
Type = int, value = 55
Type = struct { name string }, value = {Naveen R}
Type assertion
Type assertion est utilisé pour extraire la valeur implicite de l'interface.
i.(T) est le syntaxe utilisé pour avoir la valeur implicite de l'interface i
qui est de type concret T
.
Exemple:
package main
import (
"fmt"
)
func assert(i interface{}) {
s := i.(int) //extraire la valeur implicite int de i
fmt.Println(s)
}
func main() {
var s interface{} = 56
assert(s)
}
Le type concret de s
est int
. On utilise le syntaxe i.(int)
pour extraire la valeur implicite de i. Le programme affiche 56
.
Qu'est ce qui va se passer si le type concret dans le programme suivant n'est pas int?
package main
import (
"fmt"
)
func assert(i interface{}) {
s := i.(int)
fmt.Println(s)
}
func main() {
var s interface{} = "Steven Paul"
assert(s)
}
Dans le programme ci-dessus, on passe s
de type concret string
à la fonction assert
qui essaie d'en extraire la valeur int. Ce programme va lancer un message: panic: interface conversion: interface {} is string, not int
.
Pour résoudre ce problème, on peut utiliser le syntaxe suivant:
v, ok := i.(T)
Si le type concret de i
est T
alors v
va avoir la valeur implicite de i
et ok
va être true.
Si le type concret de i
n'est pas T
alors ok
va être false et v
va avoir la valeur zéro du type T
et le programme ne lancera aucun message.
package main
import (
"fmt"
)
func assert(i interface{}) {
v, ok := i.(int)
fmt.Println(v, ok)
}
func main() {
var s interface{} = 56
assert(s)
var i interface{} = "Steven Paul"
assert(i)
}
Quand Steven Paul
est passé à la fonction assert
, ok
va être false puisque le type concret de i
n'est pas int
et v
va avoir la valeur 0. Ce programme affiche,
56 true
0 false
Type Switch
Le type switch est utilisé pour comparer le type concret d'une interface avec des types multiples dans différents cas de déclarations. Cela est similaire à switch case. La seule différence est que cases indiquent les types et non pas les valeurs en switch(normal).
Le syntaxe pour type switch est similaire pour Type assertion. Dans le syntaxe i.(T)
pout le Type assertion. Le type T
doit être remplacé par le mot clé type
pour le type switch.
Exemple:
package main
import (
"fmt"
)
func findType(i interface{}) {
switch i.(type) {
case string:
fmt.Printf("Je suis une chaine de caractères et ma valeur est %s\n", i.(string))
case int:
fmt.Printf("Je suis un int et ma valeur est %d\n", i.(int))
default:
fmt.Printf("type inconnu\n")
}
}
func main() {
findType("Naveen")
findType(77)
findType(89.98)
}
Dans le programme ci-dessus, switch i.(type)
indique le type switch. Chacune des déclarations de case(cas) compare le type concret de i
à un type spécifique. Si l'un des cas est correspondant, la bonne déclaration est affichée. La sortie du programme est,
Je suis une chaine de caractères et ma valeur est Naveen
Je suis un int et ma valeur est 77
type inconnu
Il est aussi possible de comparer un type à une interface. Si on a un type et que ce type implémente une interface, il est possible de comparer ce type avec l'interface qui l'implémente.
Exemple:
package main
import "fmt"
type Describer interface {
Describe()
}
type Person struct {
name string
age int
}
func (p Person) Describe() {
fmt.Printf("%s a %d ans", p.name, p.age)
}
func findType(i interface{}) {
switch v := i.(type) {
case Describer:
v.Describe()
default:
fmt.Printf("type inconnu\n")
}
}
func main() {
findType("Naveen")
p := Person{
name: "Naveen R",
age: 25,
}
findType(p)
}
Dans le programme ci-dessus, la structure Person
implémenter l'interface Describer
. Dans la déclaration du cas case Describer: v.Describe()
, v
est comparé au type interface Describer
. p
implémente Describer
et par conséquent ce cas est satisfait et la méthode Describer
est appelée quand le contrôle atteint fintType(p)
.
La sortie du programme est:
type inconnu
Naveen R a 25 ans
Posted on Utopian.io - Rewarding Open Source Contributors
Source: https://golangbot.com/interfaces-part-2/
Not indicating that the content you copy/paste is not your original work could be seen as plagiarism.
These are some tips on how to share content and add value:
Repeated plagiarized posts are considered spam. Spam is discouraged by the community, and may result in action from the cheetah bot.
Creative Commons: If you are posting content under a Creative Commons license, please attribute and link according to the specific license. If you are posting content under CC0 or Public Domain please consider noting that at the end of your post.
If you are actually the original author, please do reply to let us know!
Thank You!
More Info: Abuse Guide - 2017.
Your contribution cannot be approved because it does not follow the Utopian Rules.
Source
You can contact us on Discord.
[utopian-moderator]
Congratulations @raptorjesus! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Congratulations @raptorjesus! You received a personal award!
Click here to view your Board of Honor
Do not miss the last post from @steemitboard:
Congratulations @raptorjesus! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!