结构体是由一系列相同或不相同类型数据组成的数据集合。 结构体的成员(字段)的特性:
- 字段名必须唯一
- 字段有自己的类型和值
- 字段的类型也可以是结构体,甚至是字段所在结构体的类型
结构体定义格式如下:
代码语言: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...
图片及部分相关技术知识点来源于网络搜索,侵权删!