golang - 结构体

1,219 阅读4分钟

这是我参与8月更文挑战的第19天,活动详情查看:8月更文挑战

什么是结构体

golang中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。结构体是由一些列具有相同类型或不同类型的数据构成的数据集合

结构体是值类型,用于自定义数据类型与实现面向对象

作用与应用场景

作用: 用于定义自定义类型

应用场景: 自定义数据类型 面向对象

结构体的定义和初始化

type struct_variable_type struct {
    member definition;
    member definition;
    ...
    member definition;
}

一旦定义了结构体类型,它就能用于变量的声明

variable_name := structure_variable_type { valur1, value2...valuen } 

初始化结构体

// 1. 按照顺序提供初始化值
p := person("Tom", 25)

// 2. 通过field:value的方式初始化,这样可以任意顺序
p := person{ age: 24, name: "Tom" }

// 3. new方式,未设置初始值的,会赋予类型的默认初始值
p := new(person)
p.age = 24

定义自定义类型的方式1

type structValue struct {}

type integer int
type intVariables int
type integerVariables integer
intVariables = integerVariables

// 基于一种类型去创建另一种类型,被认为是两种不同的类型
fmt.Println(intVariables, integerVariables)

// 无法相互赋值,如何赋值? 类型转换
intVariables = int(integerVariables)

定义自定义类型的方式2 结构体

结构体字段可以是任意类型,以及结构体本身,函数,接口等

结构体类型是某一类具体事物的抽象

以中秋节的月饼举例,月饼的模板,做出月饼

通过组合一定数据的字段来完成

type 结构体名 struct {
    field1 type1
    field2 type2
    ...
}

结构体的使用方式1

type userinfo struct {
    name string
    age int
    height float32
    eduschool string
    hobby []string
    moreinfo map[string]interface{}
}

// 使用
var afei userinfo
afei.name = "阿肥"
afei.age = 22
afei.height = 156
afei.eduschool = "五道口职业技术学院"
afei.hobby = []string{"抖音", "代码", "发呆"}
afei.moreinfo = map[string]interface{} {
    "work": "某机器人公司",
    "duty": "go语言工程师"
}

结构体的使用方式2

:=简短声明来实现一个结构变量

第二种形式没有字段名,只声明对应的值,每个值也可以分别占一行,不过习惯上这种形式会写在一行里,结尾不需要逗号。这种形式下,值的顺序很重要,必须要和结构声明中字段的顺序一致,同时在我们不置顶字段名称的时候,结构体当中的所有字段必须全部赋值

// 1. 声明变量
// 2. 初始化
afei := userinfo {
    name:      "阿肥",
    age:       22,
    height:    156,
    eduschool: "五道口职业技术学院",
    hobby:     []string{"抖音", "代码", "发呆"},
    moreinfo:  map[string]interface{} {
                    "work": "某机器人公司",
                    "duty": "go语言工程师"
                }

不指定字段名的时候,需要严格的按照定义结构体时候的顺序赋值
指定字段名的时候,可以不按定义结构体时候的顺序赋值
对结构体赋值时,如果各个字段不在一行,最后一个字段必须添加逗号
对结构体赋值时,如果各个字段在同一行,则最后的一个字段可以不添加逗 号

xiaoge := userinfo{"小哥",12,120,"小学",[]string{"学习","玩","打游戏"}, map[string]interface{}{"年级":"六年级"}}
    fmt.Printf("xiaoge=%v\n",xiaoge)

结构体的使用方式3 new

使用new new(int),new(string),new(T) 返回结构体指针

//var t *T
//t = new(T)
var xiaoming *userinfo
xiaoming = new(userinfo)
(*xiaoming).name = "小明"
(*xiaoming).age = 12
(*xiaoming).eduschool = "北京小学"
//xiaoming->(*xiaoming) go语言编译器自动转换
xiaoming.hobby = []string{"学习","玩","打游戏"}
fmt.Println(xiaoming)

结构体的使用方式4 &地址符

同样是返回的结构体指针

var xiaohong *userinfo = &userinfo{
    "小红",12,120,"小学",[]string{"学习","玩","打游戏"}, map[string]interface{}{"年级":"五年级"},
}

结构体注意事项

不指定字段名的时候,需要严格的按照定义结构体时的顺序赋值

  • 结构体是值类型
  • 结构体之间是否可以相互转换? 可以转换,前提条件:具有相同的字段(个数,类型,名称)
  • 结构体可以做另一个结构体字段的类型
  • 结构体变量赋值,各字段不在同一行时,最后一个字段必须要加逗号
  • 结构体变量赋值,各字段在同一行时,最后一个字段的逗号可加,可不加