Go 开发常用操作技巧--结构体

简介: 结构体是由一系列相同或不相同类型数据组成的数据集合

结构体是由一系列相同或不相同类型数据组成的数据集合。 结构体的成员(字段)的特性:

  • 字段名必须唯一
  • 字段有自己的类型和值
  • 字段的类型也可以是结构体,甚至是字段所在结构体的类型

结构体定义格式如下:

type 类型名 struct{
  字段1 类型1
  字段2 类型2
  //...
}
复制代码

结构体初始化

type Mystruct struct {
  Name    string
  Address string
}
//方法一
var person Mystruct
person.Name = "test"
person.Address = "beijing"
//方法二
person1 := Mystruct{"test","beijing"}
//方法三
//(*person2).Name 等同于 person2.Name
var person2 = new(Mystruct)
person2.Name = "test"
person2.Address = "beijing"
//方法四
//(*Mystruct).Name 等同于 person3.Name
var person3 = &Mystruct{}
(*person3).Name = "test"
(*person3).Address = "beijing"
复制代码

结构体排序

可以通过 sort.Slice() 函数进行结构体的排序

示例:

package main
import (
  "fmt"
  "sort"
)
type Mystruct struct {
  Name    string
  Address string
}
func main() {
  persons := []Mystruct{
    {"test2", "aa"},
    {"test1", "bb"},
    {"test3", "cc"},
  }
  fmt.Println(persons)
  sort.Slice(persons, func(i, j int) bool {
    return persons[i].Name < persons[j].Name || persons[i].Address < persons[j].Address
  })
  fmt.Println(persons)
}
复制代码

运行结果:

[{test2 aa} {test1 bb} {test3 cc}]
[{test1 bb} {test2 aa} {test3 cc}]
复制代码

结构体继承

Go 语言中没有 extends 关键字,不能像其他语言那样去实现类的继承。在Go中,使用的是 interface 实现的功能组合,以组合的形式来实现继承。

如下我们创建一个父类结构体 Father,再用子类 Child 继承父类,实现在 Child 中调用父类的方法,示例:

package main
import (
  "fmt"
)
type Father struct {
  Name string
}
func (f Father) Say(){
  fmt.Println("father...")
}
type Child struct {
  Father
}
func main() {
  child := Child{}
  child.Father.Say() // father...
  //直接使用下面的写法也可以,Go语言做了相关的优化,直接调用方法也可以找到父类中的方法
  child.Say() // father...
}
复制代码

改写父类的方法

package main
import (
  "fmt"
)
type Father struct {
  Name string
}
func (f Father) Say(){
  fmt.Println("father...")
}
type Child struct {
  Father
}
func (c Child)Say(){
  fmt.Println("child start...")
  c.Father.Say()
  fmt.Println("child end...")
}
func main() {
  child := Child{}
  child.Father.Say()
  //被 child 改写后,下面调用的就是自身的方法
  child.Say()
}
复制代码

运行结果:

father...
child start...
father...
child end...
复制代码

匿名结构体

顾名思义,匿名结构体就是没有名字的结构体,示例如下:

package main
import "fmt"
func main() {
  book := struct {   // 无需事先声明
    title  string
    id     int
  }{
    title:  "Go语言",  // 定义完成之后,即可进行初始化  
    id:     123456,
  }
  fmt.Println("title ", book.title)
  fmt.Println("id", book.id)
}
// 打印结果
// title  Go语言
// id 123456
复制代码

结构体字段标签

结构体字段标签(tag)是结构体额外的信息,用于对字段进行说明。在 json 序列化及对象关系映射时,会用到此标签。标签信息都是静态的,无需实例化结构体,可以通过反射来获得。

标签在结构体后面,由一个或多个键值组成,键值间使用空格分隔:

key1:"value1" key2:"value2"

使用反射获取结构体标签信息:

package main
import (
  "fmt"
  "reflect"
)
type Test struct {
  Name string `json:"name"`
}
func main() {
  var test = Test{}
  //反射获取标签信息
  typeTest := reflect.TypeOf(test)
  testFieldName, ok := typeTest.FieldByName("Name")
  if ok {
    fmt.Println(testFieldName.Tag.Get("json"))
  }
}
// 打印结果
// name
复制代码

多态

  • 继承主要在于: 解决代码的复用性和可维护性;
  • 接口主要在于: 接口设计好各种规范方法,让其它自定义类型实现这些方法;
  • 接口比继承更加灵活,继承是满足is-a的关系,接口是满足like-a的关系;

Go 中的多态是通过接口实现的:

package main
import "fmt"
type People interface {
  Say()
}
type Student struct {}
type Teacher struct {}
func (p *Student) Say(){
  fmt.Println("Student...")
}
func (c *Teacher) Say(){
  fmt.Println("Teacher...")
}
func hello(p People) {
  p.Say()
}
func main(){
  var student = new(Student)
  var teacher = new(Teacher)
  hello(student)
  hello(teacher)
}
复制代码

打印结果:

Student...
Teacher...


相关文章
|
23天前
|
程序员 Go
go语言中结构体(Struct)
go语言中结构体(Struct)
97 71
|
4月前
|
缓存 弹性计算 API
用 Go 快速开发一个 RESTful API 服务
用 Go 快速开发一个 RESTful API 服务
|
26天前
|
开发框架 Go 计算机视觉
纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架
开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C++ 库,如 OpenCV 或 dlib,但通过 cgo 调用 C 程序会引入巨大的延迟,并在性能方面产生显著的权衡。此外,在许多情况下,在各种平台上安装 OpenCV 是很麻烦的。使用纯Go开发的插件不仅在开发时方便,在项目部署和项目维护也能省很多时间精力。
|
1月前
|
存储 Rust Go
Go nil 空结构体 空接口有什么区别?
本文介绍了Go语言中的`nil`、空结构体和空接口的区别。`nil`是预定义的零值变量,适用于指针、管道等类型;空结构体大小为0,多个空结构体实例指向同一地址;空接口由`_type`和`data`字段组成,仅当两者均为`nil`时,空接口才为`nil`。
Go nil 空结构体 空接口有什么区别?
|
1月前
|
编译器 Go
探索 Go 语言中的内存对齐:为什么结构体大小会有所不同?
在 Go 语言中,内存对齐是优化内存访问速度的重要概念。通过调整数据在内存中的位置,编译器确保不同类型的数据能够高效访问。本文通过示例代码展示了两个结构体 `A` 和 `B`,尽管字段相同但排列不同,导致内存占用分别为 40 字节和 48 字节。通过分析内存布局,解释了内存对齐的原因,并提供了优化结构体字段顺序的方法,以减少内存填充,提高性能。
42 3
|
1月前
|
Go 数据安全/隐私保护 开发者
Go语言开发
【10月更文挑战第26天】Go语言开发
42 3
|
1月前
|
Java 程序员 Go
Go语言的开发
【10月更文挑战第25天】Go语言的开发
35 3
|
3月前
|
Go
Go to Learn Go之结构体
Go to Learn Go之结构体
43 5
|
3月前
|
存储 Shell Go
Go语言结构体和元组全面解析
Go语言结构体和元组全面解析
|
4月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
163 1
go语言后端开发学习(四) —— 在go项目中使用Zap日志库