前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 开发常用操作技巧--结构体

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

作者头像
微客鸟窝
发布2023-01-09 19:19:31
2700
发布2023-01-09 19:19:31
举报
文章被收录于专栏:Go语言指北

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

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

结构体定义格式如下:

代码语言: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...

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微客鸟窝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 结构体初始化
  • 结构体排序
  • 结构体继承
    • 改写父类的方法
    • 匿名结构体
    • 结构体字段标签
    • 多态
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档