Golang 20 : Les interfaces(Part II)

in #utopian-io7 years ago (edited)

Les interfaces(Part II)

image.png

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 Talors 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

Sort:  

Your contribution cannot be approved because it does not follow the Utopian Rules.

  • You must be author of the tutorial.
    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

Upvote this notification to help all Steemit users. Learn why here!

Congratulations @raptorjesus! You received a personal award!

1 Year on Steemit

Click here to view your Board of Honor

Do not miss the last post from @steemitboard:

Saint Nicholas challenge for good boys and girls

Support SteemitBoard's project! Vote for its witness and get one more award!

Congratulations @raptorjesus! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

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!

Coin Marketplace

STEEM 0.17
TRX 0.13
JST 0.027
BTC 61020.40
ETH 2603.09
USDT 1.00
SBD 2.65