Maison  >  Article  >  développement back-end  >  En savoir plus sur les assertions de type Golang

En savoir plus sur les assertions de type Golang

藏色散人
藏色散人avant
2021-05-27 15:27:412509parcourir

Ce qui suit est une introduction aux assertions de type golang de la colonne du didacticiel golang. J'espère que cela sera utile aux amis dans le besoin !

Il existe une fonction serialize() en php qui peut sérialiser des tableaux en chaînes pour le stockage et la transmission

Si vous souhaitez désérialiser ce type de chaîne, vous n'avez besoin que d'une simple fonction en php. La fonction unserialize() peut être complétée. Mais ce n'est pas si simple en Golang. Cela nécessite beaucoup d'efforts et d'écriture de beaucoup de code.

En ce moment, j'ai juste envie de soupirer, php est vraiment le meilleur langage au monde !

J'ai rencontré un tel problème dans le développement d'aujourd'hui. Je dois utiliser Golang pour analyser les chaînes sérialisées PHP. J'ai trouvé un package d'analyse sur github, mais j'ai trouvé que le résultat après l'analyse est un type d'interface{ }.

Soudain, je ne savais plus par où commencer. Je n'arrêtais pas de penser que les données étaient en fait une carte, mais après l'avoir analysée, j'ai obtenu une interface{} Comment puis-je l'utiliser ? J'ai l'impression que je dois utiliser des assertions de type. Mais je ne sais pas comment l'utiliser, alors je suis allé voir la communauté et j'ai demandé, en espérant que les grands pourront me donner une réponse.

Cela fonctionne vraiment très bien.

Postez le code ci-dessous :

package main

import (
	"github.com/yvasiyarov/php_session_decoder/php_serialize"
	"fmt"
	"log"
)


func main() {
        // 序列化后的字符串
	str := `a:3:{s:4:"name";s:3:"tom";s:3:"age";s:2:"23";s:7:"friends";a:2:{i:0;a:1:{s:4:"name";s:5:"jerry";}i:1;a:1:{s:4:"name";s:4:"jack";}}}`
	
        // 反序列化
        decoder := php_serialize.NewUnSerializer(str)
	if result, err := decoder.Decode(); err != nil {
		panic(err)
	} else {
                // 此处进行类型断言
		decodeData, ok := result.(php_serialize.PhpArray)
		if !ok {
			log.Println(err)
		}

                // 断言后,即可获取内容
		name := decodeData["name"]
		age := decodeData["age"]
		fmt.Println(name, age)

                // 内层数据仍需再次断言
		friends, ok := decodeData["friends"].(php_serialize.PhpArray)
		if !ok {
			log.Println(err)
		}

                // 断言成功后即可获取内部数据
		for _,v := range friends {
			fmt.Printf("type:%T, value:%+v\n", v,v )
			friend, ok := v.(php_serialize.PhpArray)
			if !ok {
				log.Println(err)
			}
			friendName := friend["name"]
			fmt.Println(friendName)
		}
	}
}

Cela peut être grossièrement compris comme ceci : quel que soit le type d'une variable, quel type d'assertion est faite Après l'assertion, le résultat peut être obtenu

Comment déterminer le type d'une variable ?

Imprimez-le : fmt.Printf("%T", verb)

L'espace réservé %T peut afficher le type de la variable

Voici un exemple :

package main

import (
	"github.com/yvasiyarov/php_session_decoder/php_serialize"
	"fmt"
	"log"
)

func main() {
	// 序列化后的字符串
	str := `a:3:{s:4:"name";s:3:"tom";s:3:"age";s:2:"23";s:7:"friends";a:2:{i:0;a:1:{s:4:"name";s:5:"jerry";}i:1;a:1:{s:4:"name";s:4:"jack";}}}`
	
	// 反序列化
	decoder := php_serialize.NewUnSerializer(str)
	result, err := decoder.Decode()
	if err != nil {
		panic(err)
	}
	// 类型断言
	t := result.(php_serialize.PhpArray)
	strVal := php_serialize.PhpValueString(t["name"])
	fmt.Println(strVal)
	
	switch t := result.(type) {
	default:
		fmt.Printf("unexpected type %T\n", t)
	case php_serialize.PhpArray:
		fmt.Println(t)
		fmt.Println(t["name"])
		fmt.Println(t["age"])

		switch f := t["friends"].(type) {
		default:
			fmt.Printf("unexpected type %T\n", t)
		case php_serialize.PhpArray:
			fmt.Println(f)
			fmt.Println(f[0])
			fmt.Println(f[1])
		}
	}
}

Les deux démos ci-dessus peuvent obtenir l'effet, mais elles sont écrites de différentes manières.

Plus tard, j'ai découvert un autre package, qui peut également obtenir l'effet :

package main

import (
	"fmt"
	"log"
	"github.com/wulijun/go-php-serialize/phpserialize"
)

func main() {
	str := `a:3:{s:4:"name";s:3:"tom";s:3:"age";s:2:"23";s:7:"friends";a:2:{i:0;a:1:{s:4:"name";s:5:"jerry";}i:1;a:1:{s:4:"name";s:4:"jack";}}}`
	decodedRes, err := phpserialize.Decode(str)
	if err != nil {
		panic(err)
	}
	//fmt.Printf("%T\n", decodedRes) //type is map[interface{}]interface{}

	//type assert
	decodedData, ok := decodedRes.(map[interface{}]interface{})
	if !ok {
		fmt.Printf("unexpected type %T\n", decodedRes)
	}
	fmt.Println(decodedData["name"])
	fmt.Println(decodedData["age"])

	//fmt.Printf("%T\n", decodedData["friends"]) // type is map[interface{}]interface{}
	// type assert
	friendsRes, ok := decodedData["friends"].(map[interface{}]interface{})
	if !ok {
		fmt.Printf("unexpected type %T\n", decodedData["friends"])
	}
	for _,v := range friendsRes {
		//fmt.Printf("type: %T, val: %#v\n", v,v) // type is map[interface{}]interface{}
		friend, ok := v.(map[interface{}]interface{})
		if !ok {
			fmt.Printf("unexpected type %T\n", decodedData["friends"])
		}
		//fmt.Printf("type: %T, val: %#v\n", friend,friend) // type is map[interface{}]interface{}
		fmt.Println(friend["name"])
	}
}

Les types de tous les résultats analysés par ce package sont map[interface{}]interface{ }, vous pouvez donc être plus simple et plus brut lorsque vous faites des assertions de type.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer