Go Struct结构体的具体实现

 更新时间:2023年03月15日 10:35:44   作者:富士康质检员张全蛋  
Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性,本文主要介绍了Go Struct结构体的具体实现,感兴趣的可以了解一下

什么是结构体

Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念。(继承,多态,封装)

Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。

1. 基本实例化(方法1)

只有当结构体实例化时,才会真正地分配内存(其实也就是使用new),也就是必须实例化后才能使用结构体的字段。

结构体本身也是一种类型,我们可以像声明内置类型一样使用 var 关键字声明结构体类型。

type person struct { 
name string 
city string 
age int 
}
 
func main() { 
var p1 person 
p1.name = "张三" 
p1.city = "北京" 
p1.age = 18
fmt.Printf("p1=%v\n", p1) // p1={张三 北京 18}
fmt.Printf("p1=%#v\n", p1) // p1=main.person{name:"张三", city:"北京", age:18} }

2. new实例化(方法2)

我们还可以通过使用 new 关键字对结构体进行实例化,得到的是结构体的地址

从打印的结果中我们可以看出 p2 是一个结构体指针。

注意:在 Golang 中支持对结构体指针直接使用.来访问结构体的成员。

p2.name = "张三" 其实在底层是 (*p2).name = "张三"

type person struct {
name string
city string
age int
}
 
func main() {
    var p2 = new(person)
    p2.name = "张三"
    p2.age = 20
    p2.city = "北京"
    fmt.Printf("p2=%#v \n", p2) //p2=&main.person{name:"张三", city:"北京", age:20}
}

3. 键值对初始化(方法3 结构体能够使用指针就使用指针)

type person struct {
name string
city string
age int
}
 
func main() {
    p4 := &person{
    name: "zhangsan",
    city: "北京",
    age: 18,
    }
    // p4=&main.person{name:"zhangsan", city:"北京", age:18}
    fmt.Printf("p4=%#v\n", p4)
}

结构体方法和接收者

1. 结构体说明

在 go 语言中,没有类的概念但是可以给类型(结构体,自定义类型)定义方法。所谓方法就是定义了接收者的函数。

Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。

方法的定义格式如下:

func (接收者变量 接收者类型) 方法名(参数列表) (返回值) {
函数体
}

2. 结构体方法和接收者

给结构体 Person 定义一个方法打印 Person 的信息

type Person struct {
    name string
    age int8
}
 
func (p Person) printInfo() {
    fmt.Printf("姓名:%v 年龄:%v", p.name, p.age) // 姓名:小王子 年龄:25
}
 
func main() {
    p1 := Person{
        name: "小王子",
        age: 25,
    }
    p1.printInfo() // 姓名:小王子 年龄:25
}

3. 值类型和指针类型接收者

实例1:给结构体 Person 定义一个方法打印 Person 的信息

值类型的接收者

  • 当方法作用于值类型接收者时,Go 语言会在代码运行时将接收者的值复制一份。
  • 在值类型接收者的方法中可以获取接收者的成员值,但 修改操作只是针对副本 ,无法修改接收者变量本身。

指针类型的接收者

  • 指针类型的接收者由一个结构体的指针组成
  • 由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。
  • 这种方式就十分接近于其他语言中面向对象中的 this 或者 self

方法大部分时候是自己处理自己的数据,总结如下:

encoding-json包

1. struct与json

比如我们 Golang 要给 App 或者小程序提供 Api 接口数据,这个时候就需要涉及到结构体和Json 之间的相互转换。

  • GolangJSON 序列化是指把结构体数据转化成 JSON 格式的字符串
  • Golang JSON 的反序列化是指把 JSON 数据转化成 Golang 中的结构体对象
  • Golang 中 的 序 列 化 和 反 序 列 化 主 要 通 过 "encoding/json" 包 中 的 json.Marshal() 和json.Unmarshal()方法实现

struct转Json字符串

type Student struct {
ID int
Gender string
name string //私有属性不能被 json 包访问
Sno string
}
 
func main() {
 
var s1 = Student{
    ID: 1,
    Gender: "男",
    name: "李四",
    Sno: "s0001",
}
 
fmt.Printf("%#v\n", s1) // main.Student{ID:1, Gender:"男", name:"李
四",Sno:"s0001"}
var s, _ = json.Marshal(s1)
jsonStr := string(s)
fmt.Println(jsonStr) // {"ID":1,"Gender":"男","Sno":"s0001"}
}

Json字符串转struct

type Student struct {
ID int
Gender string
Name string
Sno string
}
 
func main() {
    var jsonStr = `{"ID":1,"Gender":"男","Name":"李四","Sno":"s0001"}`
    var student Student //定义一个 Monster 实例
    err := json.Unmarshal([]byte(jsonStr), &student)
    if err != nil {
    fmt.Printf("unmarshal err=%v\n", err)
}
 
// 反序列化后 student=main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}
student.Name="张三"
fmt.Printf("反序列化后 student=%#v student.Name=%v \n", student, student.Name)
}

2. struct tag

1)Tag标签说明

  • Tag 是结构体的元信息,可以在运行的时候通过反射的机制读取出来。
  • Tag 在结构体字段的后方定义,由一对反引号包裹起来

具体的格式如下:

key1:"value1" key2:"value2"

  • 结构体 tag 由一个或多个键值对组成。键与值使用冒号分隔,值用双引号括起来。
  • 同一个结构体字段可以设置多个键值对 tag,不同的键值对之间使用空格分隔。

注意事项:

为结构体编写 Tag 时,必须严格遵守键值对的规则。

结构体标签的解析代码的容错能力很差,一旦格式写错,编译和运行时都不会提示任何错误,通过反射也无法正确取值。例如不要在 key 和 value 之间添加空格。

Tag结构体转化Json字符串

type Student struct {
ID int `json:"id"` //通过指定 tag 实现 json 序列化该字段时的 key(表示在做json操作的时候,用json指定的字段名)
Gender string `json:"gender"`
Name string
Sno string
}
 
func main() {
    var s1 = Student{
    ID: 1,
    Gender: "男",
    Name: "李四",
    Sno: "s0001",
}
 
// main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}
fmt.Printf("%#v\n", s1)
var s, _ = json.Marshal(s1)
jsonStr := string(s)
fmt.Println(jsonStr) // {"id":1,"gender":"男","Name":"李四","Sno":"s0001"}
}

Json字符串转成Tag结构体

type Student struct {
    ID int `json:"id"` //通过指定 tag 实现 json 序列化该字段时的 key
    Gender string `json:"gender"`
    Name string
    Sno string
}
 
func main() {
    var s2 Student
    var str = `{"id":1,"gender":"男","Name":"李四","Sno":"s0001"}`
    err := json.Unmarshal([]byte(str), &s2)
    if err != nil {
    fmt.Println(err)
    }
    // main.Student{ID:1, Gender:"男", Name:"李四", Sno:"s0001"}
    fmt.Printf("%#v", s2)
}

以上就是Go Struct结构体的具体实现的详细内容,更多关于Go Struct结构体的资料请关注脚本之家其它相关文章!

相关文章

  • golang 使用chromedp获取页面请求日志network

    golang 使用chromedp获取页面请求日志network

    这篇文章主要为大家介绍了golang 使用chromedp获取页面请求日志network方法实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 一文带你了解Go中跟踪函数调用链的实现

    一文带你了解Go中跟踪函数调用链的实现

    这篇文章主要为大家详细介绍了go如何实现一个自动注入跟踪代码,并输出有层次感的函数调用链跟踪命令行工具,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • golang踩坑实战之channel的正确使用方式

    golang踩坑实战之channel的正确使用方式

    Golang channel是Go语言中一个非常重要的特性,除了用来处理并发编程的任务中,它还可以用来进行消息传递和事件通知,这篇文章主要给大家介绍了关于golang踩坑实战之channel的正确使用方式,需要的朋友可以参考下
    2023-06-06
  • Go语言使用Etcd实现分布式锁

    Go语言使用Etcd实现分布式锁

    etcd是近几年比较火热的一个开源的、分布式的键值对数据存储系统,本文将介绍如何利用Etcd实现分布式锁,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-05-05
  • Golang数组的传递详解

    Golang数组的传递详解

    今天小编就为大家分享一篇关于Golang数组的传递详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • go类型转换及与C的类型转换方式

    go类型转换及与C的类型转换方式

    这篇文章主要介绍了go类型转换及与C的类型转换方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • go语言if/else语句简单用法示例

    go语言if/else语句简单用法示例

    这篇文章主要介绍了go语言if/else语句用法,结合实例形式分析了go语言if else语句的判定与流程控制技巧,需要的朋友可以参考下
    2016-05-05
  • 浅析go语言如何实现协程的抢占式调度的

    浅析go语言如何实现协程的抢占式调度的

    go语言通过GMP模型实现协程并发,为了避免单协程持续持有线程导致线程队列中的其他协程饥饿问题,设计者提出了一个抢占式调度机制,本文会基于一个简单的代码示例对抢占式调度过程进行深入讲解剖析
    2024-04-04
  • 如何将Golang数组slice转为逗号分隔的string字符串

    如何将Golang数组slice转为逗号分隔的string字符串

    这篇文章主要介绍了如何将Golang数组slice转为逗号分隔的string字符串问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Redis BloomFilter布隆过滤器原理与实现

    Redis BloomFilter布隆过滤器原理与实现

    你在开发或者面试过程中,有没有遇到过 海量数据需要查重,缓存穿透怎么避免等等这样的问题呢?下面这个东西超棒,好好了解下,面试过关斩将,凸显你的不一样
    2022-10-10

最新评论