1、定义

Go语言可以通过自定义的方式形成新的类型,结构体就是这些类型中的一种复合类型,结构体是由零个或多个任意类型的值聚合成的实体,每个值都可以称为结构体的成员。

结构体成员也可以称为“字段”,这些字段有以下特性:

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

结构体的定义格式如下:

type 类型名 struct {
    字段1 字段1类型
    字段2 字段2类型
    …
}

对各个部分的说明:

  • 类型名:标识自定义结构体的名称,在同一个包内不能重复。
  • struct{}:表示结构体类型,type 类型名 struct{}可以理解为将 struct{} 结构体定义为类型名的类型。
  • 字段1、字段2……:表示结构体字段名,结构体中的字段名必须唯一。
  • 字段1类型、字段2类型……:表示结构体各个字段的类型。

 

2、实例化

Go语言可以通过多种方式实例化结构体,根据实际需要可以选用不同的写法。

1)基本实例化格式

var ins T

其中,T 为结构体类型,ins 为结构体的实例。

使用.来访问结构体的成员变量。

示例:

package main

import "fmt"

func main() {
	type Point struct {
		X int
		Y int
	}
	var p Point
	p.X = 10
	p.Y = 20
	fmt.Printf("x = %d, y = %d\n", p.X, p.Y)
}

  

2)创建指针类型的结构体

Go语言中,还可以使用 new 关键字对类型(包括结构体、整型、浮点数、字符串等)进行实例化,结构体在实例化后会形成指针类型的结构体。

使用 new 的格式如下:

ins := new(T)

其中:

  • T 为类型,可以是结构体、整型、字符串等。
  • ins:T 类型被实例化后保存到 ins 变量中,ins 的类型为 *T,属于指针。

在Go语言中,访问结构体指针的成员变量时可以继续使用.,这是因为Go语言为了方便开发者访问结构体指针的成员变量,使用了语法糖技术,将 ins.Name 形式转换为 (*ins).Name。

示例:

package main

import "fmt"

func main() {
	type Point struct {
		X int
		Y int
	}
	p := new(Point)
	p.X = 10
	p.Y = 20
	fmt.Printf("x = %d, y = %d\n", p.X, p.Y)
}

  

3)取结构体的地址实例化

在Go语言中,对结构体进行&取地址操作时,视为对该类型进行一次 new 的实例化操作,取地址格式如下:

ins := &T{}

其中:

  • T 表示结构体类型。
  • ins 为结构体的实例,类型为 *T,是指针类型。

示例:

package main

import "fmt"

func main() {
	type Point struct {
		X int
		Y int
	}
	p := &Point{
		1,
		2,
	}
	fmt.Printf("x = %d, y = %d\n", p.X, p.Y)
}

  

3、初始化

结构体在实例化时可以直接对成员变量进行初始化,初始化有两种形式分别是以字段“键值对”形式和多个值的列表形式,键值对形式的初始化适合选择性填充字段较多的结构体,多个值的列表形式适合填充字段较少的结构体。

1)使用键值对初始化

结构体可以使用“键值对”初始化字段,每个“键”对应结构体中的一个字段,键的“值”对应字段需要初始化的值。
键值对的填充是可选的,不需要初始化的字段可以不填入初始化列表中。
结构体实例化后字段的默认值是字段类型的默认值,例如 ,数值为 0、字符串为 ""(空字符串)、布尔为 false、指针为 nil 等。

键值对初始化的格式如下:

ins := 结构体类型名{
    字段1: 字段1的值,
    字段2: 字段2的值,
    …
}

说明:

  • 结构体类型:定义结构体时的类型名称。
  • 字段1、字段2:结构体成员的字段名,结构体类型名的字段初始化列表中,字段名只能出现一次。
  • 字段1的值、字段2的值:结构体成员字段的初始值。

注意:结构体成员中只能包含结构体的指针类型,包含非指针类型会引起编译错误。

示例:

package main

import "fmt"

func main() {
	type People struct {
		name  string
		child *People
	}
	relation := &People{
		name: "爷爷",
		child: &People{
			name: "爸爸",
			child: &People{
				name: "我",
			},
		},
	}
	fmt.Println(relation.name)
	fmt.Println(relation.child.name)
	fmt.Println(relation.child.child.name)
}

  

2)使用多个值的列表初始化结构体

Go语言可以在“键值对”初始化的基础上忽略“键”,也就是说,可以使用多个值的列表初始化结构体的字段。

多个值的列表初始化格式:

ins := 结构体类型名{
    字段1的值,
    字段2的值,
    …
}

使用这种格式初始化时,需要注意:

  • 必须初始化结构体的所有字段。
  • 每一个初始值的填充顺序必须与字段在结构体中的声明顺序一致。
  • 键值对与值列表的初始化形式不能混用。

示例:

package main

import "fmt"

func main() {
	type Point struct {
		X int
		Y int
	}
	p := Point{
		1,
		2,
	}
	fmt.Printf("x = %d, y = %d\n", p.X, p.Y)
}

  

3)初始化匿名结构体

匿名结构体的初始化写法由结构体定义和键值对初始化两部分组成,结构体定义时没有结构体类型名,只有字段和类型定义,键值对初始化部分由可选的多个键值对组成,如下格式所示:

ins := struct {
    // 匿名结构体字段定义
    字段1 字段类型1
    字段2 字段类型2
    …
}{
    // 字段值初始化
    初始化字段1: 字段1的值,
    初始化字段2: 字段2的值,
    …
}

说明:

  • 字段1、字段2……:结构体定义的字段名。
  • 初始化字段1、初始化字段2……:结构体初始化时的字段名,可选择性地对字段初始化。
  • 字段类型1、字段类型2……:结构体定义字段的类型。
  • 字段1的值、字段2的值……:结构体初始化字段的初始值。

键值对初始化部分是可选的

示例:

package main

import "fmt"

func main() {
	p := struct {
		X int
		Y int
	}{
		X : 1,
		Y : 2,
	}
	fmt.Println(p)
}

   

posted on 2019-11-24 15:13  acgame  阅读(2771)  评论(0编辑  收藏  举报