首页后端开发其他后端知识Golang类型断言什么时候用,如何实现

Golang类型断言什么时候用,如何实现

时间2024-03-28 03:14:03发布访客分类其他后端知识浏览532
导读:这篇文章给大家介绍了“Golang类型断言什么时候用,如何实现”的相关知识,讲解详细,步骤过程清晰,对大家进一步学习和理解“Golang类型断言什么时候用,如何实现”有一定的帮助,希望大家阅读完这篇文章能有所收获。下面就请大家跟着小编的思路...
这篇文章给大家介绍了“Golang类型断言什么时候用,如何实现”的相关知识,讲解详细,步骤过程清晰,对大家进一步学习和理解“Golang类型断言什么时候用,如何实现”有一定的帮助,希望大家阅读完这篇文章能有所收获。下面就请大家跟着小编的思路一起来学习一下吧。


在php中有一个 serialize() 函数 可以把数组序列化成字符串进行存储和传输

如果想反序列化这种字符串,在php中只需要一个简单的unserialize() 函数就可以完成了.但是在golang中可就没有这么容易了,非得费个九牛二虎之力,写上不少代码才行。

这时候只想感叹一下,php真的是世界上最好的语言啊!

我就在今天的开发中遇到了这么个问题,需要使用golang去解析php序列化的字符串,在github上找了个解析的包,但是发现解析之后的结果是个interface{ } 类型。

顿时我就无从下手了,总在想数据实际上是一个map,但是解析后得到一个interface{ } , 这让我怎么用啊

感觉需要用类型断言,但又不太会用,遂去社区问一下吧,期望大佬们能给个答案。

实际上确实很管用。

下面贴一下代码:

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])
		}

	}

}

上面两个demo都可以达到效果,只是写法不同。

后面我又经人介绍,得到了另外一个包,也能达到效果:

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类型断言什么时候用,如何实现”的内容就介绍到这,感谢各位的阅读,相信大家对Golang类型断言什么时候用,如何实现已经有了进一步的了解。大家如果还想学习更多知识,欢迎关注网络,小编将为大家输出更多高质量的实用文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: Golang类型断言什么时候用,如何实现
本文地址: https://pptw.com/jishu/654662.html
H5页面制作和一般页面有何差异 Go语言编译的方法及过程是怎样的

游客 回复需填写必要信息