Skip to content

结构体

  • 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。

声明

  • 格式:type structName struct {}
go
// 定义结构体 定义一个教师结构体
type Teacher struct {
	Name   string
	Age    int
	school string
}

属性操作

go
var teacher1 Teacher
// 赋值
teacher1.Name = "John"
teacher1.Age = 18
teacher1.school = "Steve"
fmt.Printf("%+v \n", teacher1)

// 取值
fmt.Printf("%+v \n", teacher1.Name)

输出结果

{Name:John Age:18 school:Steve}

John

指针结构体

  • 指针结构体是指结构体的指针,它可以指向一个结构体的内存地址。
  • 通常作为函数参数时,使用指针结构体可以避免复制结构体,提高性能。
go
teacher2 := &Teacher{}
teacher2.Name = "Zhang san"
teacher2.Age = 18
teacher2.school = "Qin hua"
fmt.Printf("%+v \n", teacher2)

输出结果

&{Name:Zhang san Age:18 school:Qin hua}

可访问性

  • 结构体的名称首字母大写表示可导出(别的包可以调用),小写表示不可导出(别的包不能调用)
  • 结构体的字段首字母大写表示可导出(别的包可以调用),小写表示不可导出(别的包不能调用)

Tags

  • 格式:key1:"value1" key2:value2""
  • 在定义结构体字段时,除字段名称和数据类型外,还可以使用反引号为结构体字段声明元信息,这种元信息称为Tag。
  • Tag是一种结构体的元信息,可以在运行时通过反射机制读取出来。
go
// 定义一个教师结构体
type Teacher struct {
	Name   string `json:"name"`
	Age    int    `json:"age"`
	school string `json:"school"`
}

结构体函数

  • 结构体函数是指绑定在结构体上的函数,它可以访问结构体的字段和方法。
go
type Student struct {
	Name   string
	Age    int
	school string
}
// 特殊方法: 给Student结构体绑定String方法,会在输出时自动调用。
func (s *Student) String() string {
	return fmt.Sprintf("Name = %v,Age = %v", s.Name, s.Age)
}

// 普通方法:给Student结构体 绑定SetName方法,设置名称
func (s *Student) SetName(name string) {
	s.Name = name
}


func main() {
	stu := &Student{
		Name:   "李四",
		Age:    19,
		school: "北京大学",
	}
	stu.SetName("张三")
	fmt.Printf("%+v \n", *stu)
	fmt.Printf("%+v \n", stu) // 输出时会自动调用String方法
}

输出结果

{Name:张三 Age:19 school:北京大学}

Name = 张三,Age = 19

结构体嵌入

  • 结构体嵌入是指在一个结构体中嵌入另一个结构体,这样就可以在一个结构体中使用另一个结构体的字段和方法。
go
// 定义一个Person结构体
type Person struct {
	Name   string
	Age    int
	school string
}
// 定义一个Student结构体,其字段是Person结构体
type Student struct {
	Person Person
}

func (p *Person) Eat() {
	fmt.Printf("%v is eating", p.Name)
}
func main() {
	stu := &Student{
		Person: Person{
			Name:   "张三",
			Age:    20,
			school: "清华大学",
		},
	}
	stu.Person.Eat()
	fmt.Printf("%+v \n", stu)
}

输出结果

张三 is eating

{Person:{Name:张三 Age:20 school:清华大学}}

匿名字段

  • 匿名字段是指在结构体中定义一个字段,而不指定字段的名称,这样就可以在结构体中直接使用该字段的类型。
go
// 定义一个Person结构体
type Person struct {
	Name   string
	Age    int
	school string
}
// 定义一个Student结构体,其字段是Person结构体
type Student struct {
	Person
}

func (p *Person) Eat() {
	fmt.Printf("%v is eating", p.Name)
}

func main() {
	stu := &Student{
		Person{
			Name:   "张三",
			Age:    20,
			school: "清华大学",
		},
	}
	// 匿名字段 可以直接调用Person的方法
	stu.Eat()
}