Skip to content
On this page

结构体

声明结构体

Go
type struct_name struct {
  property_one  property_one_type
  property_two  property_two_type
  ...
}

示例

Go
type Person struct {
  name 		string
  age  		int
  isBoss 	bool
}
  • 相同类型的属性,可以写在同一行
Go

type struct_name struct {
  property_one, property_two  property_type_one
  property_three              proerty_type_two
  ...
}

示例

Go
type Peoson struct {
  name, like string
  age, level int
  isBoss     bool		 
}
  • 创建匿名结构体
Go
variable_name := struct {
  name 		string
  age  		int
  isBoss 	bool 
}{value1, value2, value3}

创建结构体

创建具名结构体

  • 使用字段名创建结构体
Go
func createStruct() {
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
	}
	person := Person {
		name: "张环",
		age: 22,
		isBoss: false,
	}
	// person is: {张环 22 false}
	fmt.Println("person is:", person)
}
  • 不使用字段名创建结构体,字段的类型要和结构体声明的顺序一致
Go
func createStruct() {
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
	}
	person1 := Person {
		"张环",
		222,
		false,
	}
	// person1 is: {张环 222 false}
	fmt.Println("person1 is:", person1)
}

创建匿名结构体

Go
func createStruct() {
	person2 := struct {
		name 	 string
		age  	 int
		isBoss bool	
	}{
		name: "张环",
		age: 22,
		isBoss: false,	
	}
	// person2 is: {张环 22 false}
	fmt.Println("person2 is:", person2)
}
  • 类型相同的字段可以放在一行声明
Go
func createStruct() {
	person3 := struct {
		name, skill string
		age        int
	}{
		"张环",
		"",
		22,
	}
	// person3 is: {张环 棍 22}
	fmt.Println("person3 is:", person3)
}

结构体的零值

  • 结构体初始化时,如果某些字段未赋值,这些字段将会默认赋为相应类型的零值
Go
func zeroValue() {
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
	}
	person5 := Person {
		name: "李朗",
	}
	// person 5 is: {李朗 0 false}
	fmt.Println("person 5 is:", person5)
	
	person6 := Person{}
	// person6 is: { 0 false}
	fmt.Println("person6 is:", person6)
}

操作结构体字段

Go
func operationStruct() {
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
	}
	person7 := Person {
		name: "蛇灵",
		age: 88,
		isBoss: true,
	}
	
	// person7 is: {蛇灵 88 true}
	fmt.Println("person7 is:", person7)
	// person7 name is: 蛇灵
	fmt.Println("person7 name is:", person7.name)
	// person7 age is: 88
	fmt.Println("person7 age is:", person7.age)
	// person7 isBoss is: true
	fmt.Println("person7 isBoss is:", person7.isBoss)

	person7.age = 22
	// person7 is: {蛇灵 22 true}
	fmt.Println("person7 is:", person7)
}

指向结构体的指针

  • person8是一个指向结构体Person指针,使用用(*person8).name访问person8name字段

  • person8.name代替(*person8).name的解引用访问

Go
func structPointer() {
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
	}
	person8 := &Person {
		name: "蛇灵",
		age: 88,
		isBoss: true,
	}
	// person8 name is: 蛇灵
	fmt.Println("person8 name is:", person8.name)
	// person8 name is: 蛇灵
	fmt.Println("person8 name is:", (*person8).name)
}

结构体中的匿名字段

  • 创建结构体时,字段可以只有类型没有字段名,这种字段称为匿名字段(Anonymous Field);

  • 对于这种形式的结构体,字段的类型即是字段的名称;

  • 一种类型的字段只能出现一次;

Go
func anonymousField() {
	type Person struct {
		string
		int
		bool
	}
	person9 := Person {
		"蛇灵",
		88,
		true,
	}
	// person9 is: {蛇灵 88 true}
	fmt.Println("person9 is:", person9)
	// person9 string is: 蛇灵
	fmt.Println("person9 string is:", person9.string)
	// person9 bool is: true
	fmt.Println("person9 bool is:", person9.bool)
}

嵌套结构体

  • 一个结构体中的字段的类型可以是另一个结构体,这样的结构体称为嵌套结构体(Nested Structs)
Go
func nestedStruct() {
	type Skill struct {
		name  string
		level int
	}
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
		skill  Skill
	}
	person10 := Person {
		name: "张环",
		age: 22,
		isBoss: false,
		skill: Skill {
			name: "",
			level: 2,
		},
	}
	// person10 is: {张环 22 false {棍 2}}
	fmt.Println("person10 is:", person10)
}

结构体中的提升字段

  • 一个结构体中,如果包含一个匿名的其他结构体,则这个匿名的结构体中的字段会合并到外面的父结构体
Go
func varivaleElevation() {
	type Skill struct {
		skillName  string
		level int
	}
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
		Skill // 注意这里
	}

	person11 := Person {
		name: "张环",
		age: 22,
		isBoss: false,
		Skill: Skill {
			skillName: "",
			level: 2,
		},
	}
	
	// person11 is: {张环 22 false {枪 2}}
	fmt.Println("person11 is:", person11)
	// person11 skillName is: 枪
	fmt.Println("person11 skillName is:", person11.skillName) 
}

结构体比较

  • 如果结构体的全部成员都是可以比较的,那么结构体也是可以比较的,那样的话两个结构体将可以使用==!=运算符进行比较

  • 也可以使用reflect.DeepEqual函数来进行比较

Go
func compareStruct() {
	type Person struct {
		name 	 string
		age  	 int
		isBoss bool
	}

	person12 := Person {
		name: "张环",
		age: 22,
		isBoss: false,
	}
	person13 := Person {
		name: "张环",
		age: 22,
		isBoss: false,
	}
	person15 := Person {
		name: "张环",
		age: 228,
		isBoss: false,
	}
	// person12和person13比较 true
	fmt.Println("person12和person13比较", person12 == person13)
	// person12和person13比较 true
	fmt.Println("person12和person13比较", reflect.DeepEqual(person12, person13))
	
	// person12和person15比较 false
	fmt.Println("person12和person15比较", person12 == person15)
	// person12和person15比较 false
	fmt.Println("person12和person15比较", reflect.DeepEqual(person12, person15))
}

为结构体定义方法

格式如下:

Go
func (arg_name struct) func_name(arguments) [func_return_value] {
  ...
}

示例

Go
type Person struct {
	name 	 string
	age  	 int
	isBoss bool
}
func (p Person) showPersonInfo() {
	fmt.Println("Person name", p.name)
	fmt.Println("Person age", p.age)
	fmt.Println("Person isBoss", p.isBoss)
}
func main() {
	person16 := Person {
		name: "张环",
		age: 22,
		isBoss: false,	
	}
	// Person name 张环
	// Person age 22
	// Person isBoss false
	person16.showPersonInfo()
}

方法传参方式

  • 如果结构体的方法需要改变原结构体的属性值,必须使用指针作为方法的接收者
Go
type Person struct {
	name 	 string
	age  	 int
	isBoss bool
}
func (p Person) showPersonInfo() {
	fmt.Println("Person name", p.name)
	fmt.Println("Person age", p.age)
	fmt.Println("Person isBoss", p.isBoss)
}

func (p *Person) changePersonAge(age int) {
	fmt.Println("修改age前Person为", *p)
	p.age = age
	fmt.Println("修改age后Person为", *p)
}
func main() {
	person17 := Person {
		name: "张环",
		age: 22,
		isBoss: false,	
	}
	// 修改age前Person为 {张环 22 false}
	// 修改age后Person为 {张环 88 false}
	person17.changePersonAge(88)
}