GO - Assertion de type

Nous savons qu'une variable d'interface peut stocker n'importe quel type de valeur (à condition que le type implémente l'interface). Comment alors déterminer le type concret stocké dans cette variable ? Deux méthodes cournates existent :

  • Assertion avec virgule-ok
  • Test avec switch
  1. Assertion avec virgule-ok

Go propose une syntaxe pour vérifier directement si une variable est d'un type donné : value, ok = element.(T). Ici value est la valeur réelle, ok est un booléen, element est la variabel interface et T est le type testé.

Si element contient effectivement une valeur de type T, ok vaut true ; sinon false.

var slice []interface{}

slice = append(slice, 10, 3.14, "aaa", demo15)

for _, elem := range slice {
    if val, ok := elem.(int); ok {
        fmt.Println("Nombre entier :", val)
    } else if val, ok := elem.(float64); ok {
        fmt.Println("Nombre flottant :", val)
    } else if val, ok := elem.(string); ok {
        fmt.Println("Chaîne :", val)
    } else if val, ok := elem.(func()); ok {
        val() // appel de fonction
    }
}

  1. Test avec switch

var slice []interface{}

slice = append(slice, 10, 3.14, "aaa", demo15)

for _, elem := range slice {
    switch val := elem.(type) {
    case int:
        fmt.Println("Nombre entier :", val)
    case float64:
        fmt.Println("Nombre flottant :", val)
    case string:
        fmt.Println("Chaîne :", val)
    case func():
        fmt.Println("Fonction :", val)
    }
}

Assertion de type

Avec if

package main

import "fmt"

type Student struct {
    name string
    id   int
}

func main() {
    items := make([]interface{}, 3)
    items[0] = 1                    // int
    items[1] = "hello go"           // string
    items[2] = Student{"mike", 666} // Student

    // Requête et assertion de type
    for index, elem := range items {
        if val, ok := elem.(int); ok {
            fmt.Printf("items[%d] est de type int, valeur = %d\n", index, val)
        } else if val, ok := elem.(string); ok {
            fmt.Printf("items[%d] est de type string, valeur = %s\n", index, val)
        } else if val, ok := elem.(Student); ok {
            fmt.Printf("items[%d] est de type Student, name = %s, id = %d\n", index, val.name, val.id)
        }
    }
}

Avec switch

package main

import "fmt"

type Student struct {
    name string
    id   int
}

func main() {
    items := make([]interface{}, 3)
    items[0] = 1                    // int
    items[1] = "hello go"           // string
    items[2] = Student{"mike", 666} // Student

    // Requête et assertion de type
    for index, elem := range items {
        switch val := elem.(type) {
        case int:
            fmt.Printf("items[%d] est de type int, valeur = %d\n", index, val)
        case string:
            fmt.Printf("items[%d] est de type string, valeur = %s\n", index, val)
        case Student:
            fmt.Printf("items[%d] est de type Student, name = %s, id = %d\n", index, val.name, val.id)
        }
    }
}

Étiquettes: Go assertion de type interfaces

Publié le 10 juillet à 06h22