golang の型アサーションについて学ぶ

藏色散人
リリース: 2021-05-27 15:28:00
転載
2507 人が閲覧しました

以下は、golang チュートリアル コラムからの golang 型アサーションの紹介です。困っている友人に役立つことを願っています。

PHP には、配列を文字列にシリアル化して保存および送信できる Serialize() 関数があります。

この種類の文字列を逆シリアル化したい場合、必要なのは単純な関数だけですphp では unserialize() 関数を完了できますが、golang ではそう簡単ではなく、多大な労力と大量のコードを記述する必要があります。

このときはため息をつきたくなるのですが、php は本当に世界で最高の言語です。

今日の開発中にこのような問題が発生しました。PHP でシリアル化された文字列を解析するには golang を使用する必要がありました。github で解析パッケージを見つけましたが、解析後の結果がインターフェイス型であることがわかりました。{ }

どこから始めればよいのか、突然わかりませんでした。データは実際にはマップだといつも思っていましたが、解析するとインターフェースが得られました。{}。どうやって使用すればよいですか?

型アサーションを使用する必要があるのですが、その使用方法がわからないので、コミュニティに行って質問し、偉い人が答えてくれることを期待しました。

実際には非常にうまく機能します。

以下のコードを貼り付けます:

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)
		}
	}
}
ログイン後にコピー

大まかに理解すると、変数の型が何であれ、どのような種類のアサーションが行われ、アサーションの後に結果が得られるかがわかります

変数の型を判断するにはどうすればよいですか?

出力します: fmt.Printf("%T",verb)

%T プレースホルダーは変数の型を表示できます

以下に別の例があります:

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])
		}
	}
}
ログイン後にコピー

上記の 2 つのデモはどちらも効果を実現できますが、作成方法が異なります。

その後、別のパッケージを紹介されましたが、これも次のような効果をもたらしました。

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"])
	}
}
ログイン後にコピー

このパッケージによって解析されたすべての結果の型は、map[interface{}]interface{ } です。型アサーションを行うときは、より単純かつ大まかに行うことができます。

以上がgolang の型アサーションについて学ぶの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート