golang中使用匿名结构体的方法

目录
  • 转化为map
  • 定义具名结构体
  • 定义匿名结构体

在一些项目中, 我们会使用json 来将字符串转为结构体,但是很多时候,这种结构体只会用一次,基本上只会用于反序列化, 对于这种只用到一次的结构体, 我们可以使用匿名结构体. 在gin 接收参数的时候会非常有用, 如我们将要接收的json 参数为

{
  "opt": "left",
  "phoneinfo": [
    {"device_id": 64, "sn": "192.168.110.65:5555"},
    {"device_id": 68, "sn": "192.168.110.164:5555"}
  ]
}

当我们尝试使用 json.Unmarshal() 函数将json 字符串转为go中的数据结构时,我们可以有以下几种方式

转化为map

map 结构需要定义key 和value的类型, 对于key 好说, 可以都定义为string, 但是对于value, 从上面的json 结构可以看出, 有字符串,也有整型,这种就不太好定义,谁知道未来会不会有新的类型,所以我们可以无脑的将json 转化为 map[string]interface{}

import (
	"encoding/json"
	"fmt"
)

func main() {
	str := `{
		"opt": "left",
		"phoneinfo": [
			{"device_id": 64, "sn": "192.168.110.65:5555"},
			{"device_id": 68, "sn": "192.168.110.164:5555"}
			]
		}`
	var s map[string]interface{}

	json.Unmarshal([]byte(str), &s)
	fmt.Printf("%#v", s)
}

这种是可以转换,但是如果要用到里面的数据就比较麻烦, 需要将 interface{} 做类型转换 如要获取到opt 参数

opt := s["opt"].(string)
fmt.Println(opt)

定义具名结构体

还有一种方式是定义一个结构体,用来接收参数 如想要接收上面的json 字符串, 可以定义下面的结构体

package main

import (
	"encoding/json"
	"fmt"
)

type phoneinfo struct {
	Device_id int    `json:"device_id"`
	Sn        string `json:"sn"`
}

type params struct {
	Opt       string      `json:"opt"`
	Phoneinfo []phoneinfo `json:"phoneinfo"`
}

func main() {
	str := `{
		"opt": "left",
		"phoneinfo": [
			{"device_id": 64, "sn": "192.168.110.65:5555"},
			{"device_id": 68, "sn": "192.168.110.164:5555"}
			]
		}`
	var s params
	json.Unmarshal([]byte(str), &s)
	fmt.Printf("%#v\n", s)
	fmt.Println(s.Opt) //left
	fmt.Println(s.Phoneinfo[0].Sn) //192.168.110.65:5555
}

定义匿名结构体

上面定义了两个结构体,但是很明显,这两个结构体只在这里使用一次, 别的地方是不会再用得到的, 所以这时我们也可以使用匿名结构体

func main() {
	str := `{
		"opt": "left",
		"phoneinfo": [
			{"device_id": 64, "sn": "192.168.110.65:5555"},
			{"device_id": 68, "sn": "192.168.110.164:5555"}
			]
		}`

	var s struct {
		Opt       string `json:"opt"`
		Phoneinfo []struct {
			Device_id int    `json:"device_id"`
			Sn        string `json:"sn"`
		} `json:"phoneinfo"`
	}
	json.Unmarshal([]byte(str), &s)
	fmt.Printf("%#v\n", s)
	fmt.Println(s.Opt)
	fmt.Println(s.Phoneinfo[0].Sn)

}

直接通过 var 变量名 struct {} 来初始化一个匿名结构体变量, 但是如果这种结构需要在多处使用,那还是单独定义一个具名结构体比较好.

到此这篇关于golang中使用匿名结构体的文章就介绍到这了,更多相关golang匿名结构体内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 解决golang结构体tag编译错误的问题

    写了一个带标签的结构体 type server struct{ XMLName xml.Name 'xml:"server"' } 解决 编译错误field tag must be a string,后来发现是后面标签上引号不正确,不应该是回车键旁边的单引号,而是数字键1旁边的单引号 type server struct{ XMLName xml.Name `xml:"server"` } 补充:golang中struct成员变量的标签(Tag)说明和获取方式 在处

  • golang 如何用反射reflect操作结构体

    背景 需要遍历结构体的所有field 对于exported的field, 动态set这个field的value 对于unexported的field, 通过强行取址的方法来获取该值(tricky?) 思路 下面的代码实现了从一个strct ptr对一个包外结构体进行取值的操作,这种场合在笔者需要用到反射的场合中出现比较多 simpleStrtuctField 函数接受一个结构体指针,因为最后希望改变其值,所以传参必须是指针.然后解引用. 接下来遍历结构体的每个field, exported字段是

  • Golang空结构体struct{}用途,你知道吗

    golang 空结构体 struct{} 可以用来节省内存 a := struct{}{} println(unsafe.Sizeof(a)) // Output: 0 理由如下: 如果使用的是map,而且map又很长,通常会节省不少资源 空struct{}也在向别人表明,这里并不需要一个值 本例说明在map里节省资源的用途: set := make(map[string]struct{}) for _, value := range []string{"apple", "o

  • golang 实现两个结构体复制字段

    实际工作中可能会有这样的场景: 两个结构体(可能类型一样), 字段名和类型都一样, 想复制一个结构体的全部或者其中某几个字段的值到另一个(即merge操作), 自然想到可以用反射实现 package main import "fmt" import "reflect" // 用b的所有字段覆盖a的 // 如果fields不为空, 表示用b的特定字段覆盖a的 // a应该为结构体指针 func CopyFields(a interface{}, b interface

  • golang修改结构体中的切片值方法

    golang修改结构体中的切片值,直接传结构体地址就可以 package main import "fmt" type rspInfo struct { KeyWords string `json:"key_words"` Value []string `json:"value"` } func setSlice(te *[]string){ str := "12" *te = append(*te,str) } //结构提传

  • golang 结构体初始化时赋值格式介绍

    golang在给结构体赋值初始值时,用:分割k,v值 x := ItemLog{ Id: GetUuid(), ItemId: u.Id, UsrId: "123", Name: u.Name, Price: u.Price, Desc: u.Desc, Status: u.Status, DevArea: u.DevArea, } 补充:golang 结构体作为map的元素时,不能够直接赋值给结构体的某个字段 引入: 错误 Reports assignments directly t

  • golang中使用匿名结构体的方法

    目录 转化为map 定义具名结构体 定义匿名结构体 在一些项目中, 我们会使用json 来将字符串转为结构体,但是很多时候,这种结构体只会用一次,基本上只会用于反序列化, 对于这种只用到一次的结构体, 我们可以使用匿名结构体. 在gin 接收参数的时候会非常有用, 如我们将要接收的json 参数为 { "opt": "left", "phoneinfo": [ {"device_id": 64, "sn":

  • 详解C++程序中定义struct结构体的方法

    什么是结构体? 简单的来说,结构体就是一个可以包含不同数据类型的一个结构,它是一种可以自己定义的数据类型,它的特点和数组主要有两点不同,首先结构体可以在一个结构中声明不同的数据类型,第二相同结构的结构体变量是可以相互赋值的,而数组是做不到的,因为数组是单一数据类型的数据集合,它本身不是数据类型(而结构体是),数组名称是常量指针,所以不可以做为左值进行运算,所以数组之间就不能通过数组名称相互复制了,即使数据类型和数组大小完全相同. 结构体的定义 定义结构体使用struct修饰符,例如: struc

  • Go语言中的匿名结构体用法实例

    本文实例讲述了Go语言中的匿名结构体用法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: package main      import (     "fmt" )      func main() {     var user struct{Name string; Gender int}     user.Name = "dotcoo"     user.Gender = 1     fmt.Printf("%#v\n",

  • go嵌套匿名结构体的初始化详解

    go匿名结构体 嵌套匿名结构体的 示例代码片. type debugConfig struct { MaxQueueDepth int `json:"maxQueueDepth"` ListenerEntries string `json:"listenerEntries"` Listeners string Logging struct { Info string `json:"info"` Protocol string `json:&quo

  • Golang实现不被复制的结构体的方法

    目录 不允许复制的结构体 实现原理 结论 不允许复制的结构体 sync包中的许多结构都是不允许拷贝的,比如sync.Cond,sync.WaitGroup,sync.Pool, 以及sync包中的各种锁,因为它们自身存储了一些状态(比如等待者的数量),如果你尝试复制这些结构体: var wg1 sync.WaitGroup wg2 := wg1 // 将 wg1 复制一份,命名为 wg2 // ... 那么你将在你的 IDE 中看到一个醒目的警告: assignment copies lock

  • python中定义结构体的方法

    Python中没有专门定义结构体的方法,但可以使用class标记定义类来代替结构体,其成员可以在构造函数__init__中定义,具体方法如下. 复制代码 代码如下: class item:    def __init__(self):        self.name = ''     # 名称        self.size = 10     # 尺寸        self.list = []     # 列表 a = item() # 定义结构对象a.name = 'cup'a.size

  • Go语言之结构体与方法

    目录 一.结构体 1.结构体的定义与使用 2.定义并赋初值 3.匿名结构体(只使用一次,没有名字) 4.结构体的零值 5.结构体的指针 6.匿名字段(字段没有名字,只有类型) 7.嵌套结构体(结构体中套结构体) 8.字段提升 9.结构体相等性 二.方法 1.方法的定义和使用 2.有了函数为啥还需要方法? 3.指针接收器与值接收器 5.匿名字段的方法(方法提升) 6.在方法中使用值接收器 与 在函数中使用值参数 7.在方法中使用指针接收器 与 在函数中使用指针参数 8.非结构体上绑定方法 一.结构

  • Golang 利用反射对结构体优雅排序的操作方法

    最近开始实习,工作技术栈主要Python和Golang,目前的任务把Python模块重构为GO模块,然后出现了一个问题,就是要将一个结构体按结构体中各个字段进行排序,然后写入Redis,对于Pyhon来说for循环就能解决,但是对于Go语言来说,每一次排序都要写一个比较函数,写出来的代码太丑,非常长,代码结构是一致,只是比较字段不一样而已,个人无法接受啊,网上搜索也没搜索到合适解决方法,所以自己想了一个解决方法来优雅排序. 比较函数: func reflectCmp(i, j interface

  • Go语言学习之结构体和方法使用详解

    目录 1. 结构体别名定义 2. 工厂模式 3. Tag 原信息 4. 匿名字段 5. 方法 1. 结构体别名定义 变量别名定义 package main import "fmt" type integer int func main() { //类型别名定义 var i integer = 1000 fmt.Printf("值: %d, 类型: %T\n", i, i) var j int = 100 j = int(i) //j和i不属于同一类型,需要转换 fm

  • Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect实例分析

    本文以实例详细描述了Objective-C中常用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect的定义及用法,具体如下所示: 1.NSRange: NSRange的原型为 typedef struct _NSRange { NSUInteger location; NSUInteger length; } NSRange; NSMakeRange的函数: NS_INLINEz是内联函数 typedef NSRange *NSRangePointer; NS_IN

随机推荐