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

2023-01-09 19:19:31 浏览数 (1)

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

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

结构体定义格式如下:

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

结构体初始化

代码语言:javascript复制
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() 函数进行结构体的排序

示例:

代码语言:javascript复制
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)
}

运行结果:

代码语言:javascript复制
[{test2 aa} {test1 bb} {test3 cc}]
[{test1 bb} {test2 aa} {test3 cc}]

结构体继承

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

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

代码语言:javascript复制
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...
}

改写父类的方法

代码语言:javascript复制
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()
}

运行结果:

代码语言:javascript复制
father...
child start...
father...
child end...

匿名结构体

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

代码语言:javascript复制
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"

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

代码语言:javascript复制
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 中的多态是通过接口实现的:

代码语言:javascript复制
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)
}

打印结果:

代码语言:javascript复制
Student...
Teacher...

图片及部分相关技术知识点来源于网络搜索,侵权删!

0 人点赞