0

0

了解学习golang类型断言

藏色散人

藏色散人

发布时间:2021-05-27 15:27:41

|

2759人浏览过

|

来源于cnblogs

转载

下面由golang教程栏目给大家介绍golang类型断言,希望对需要的朋友有所帮助!

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

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

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

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

立即学习go语言免费学习笔记(深入)”;

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

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

实际上确实很管用。

下面贴一下代码:

Yodayo
Yodayo

一个专为动漫迷和vTuber打造的AI艺术创作平台、交流社区

下载
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{},所以做类型断言的时候可以简单粗暴一些。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

210

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

247

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

356

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

409

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

490

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

201

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1458

2025.06.17

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
golang socket 编程
golang socket 编程

共2课时 | 0.1万人学习

nginx浅谈
nginx浅谈

共15课时 | 0.9万人学习

golang和swoole核心底层分析
golang和swoole核心底层分析

共3课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号