1、结构体

结构体

Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性,结构体是类型中带有成员的复合类型,属于值类型

Go 语言中的类型可以被实例化,使用new()&可以实例化该类型、获取实例的指针。

结构体成员是由一系列的成员变量构成,这些成员变量也被称为字段。字段有以下特性:

同样对于可见性,结构体的名称、结构体字段、结构体方法的名称首字母大小写规则和方法、变量名称规则相同。

定义

使用关键字type可以将各种基本类型定义为自定义类型,基本类型包括int、string、bool等。

结构体是一种复合的基本类型,通过type定义为自定义类型后,使结构体更便于使用。

type structName struct {
	filed1Name filed1Type
	filed2Name filed2Type
	filed3Name filed3Type
}

实例化

type Stu struct {
	name string
	age  int
}

使用var

由于结构体属于基本数据类型(值类型),所以在声明时,系统会自动对结构体以及结构体字段赋零值

使用var关键字

var s Stu
fmt.Println(s) // main.Stu{name:"", age:0}

使用new

sp := new(Stu)
s := *sp
fmt.Printf("%#v\n", s) // main.Stu{name:"", age:0}

初始化并赋初始值

可以在大括号中以键值对成员声明顺序的方式进行赋值

s1 := Stu{}
fmt.Printf("%#v\n", s1) // main.Stu{name:"", age:0}

s2 := Stu{"lucy", 18}
fmt.Printf("%#v\n", s2) // main.Stu{name:"lucy", age:18}

s3 := Stu{name: "tom", age: 25}
fmt.Printf("%#v\n", s3) // main.Stu{name:"tom", age:25}

// 这种方法也可以直接获取结构体指针
s := &Stu{"lucy", 18}
fmt.Printf("%T\n", s)  // *main.Stu
fmt.Printf("%#v\n", s) // &main.Stu{name:"lucy", age:18}

读写字段

结构体变量结构体指针都可以使用操作符.对进行读写操作

package main

import "fmt"

type Stu struct {
	name string
	age  int
}

func main() {
	s := Stu{"lucy", 18}
	s.name = "tom"
	fmt.Println(s) // {tom 18}

	sp := &s
	sp.name = "lily"
	fmt.Println(s) // {lily 18}
}

结构体方法与接收者

在Go语言中,没有类的概念但是可以给结构体、自定义类型定义方法。Go 方法是作用在接收者(receiver)上的一个函数,接受者就是结构体、自定义类型的实例,类似于其他语言中的thisself

使用接收者,就可以直接在实例后使用.来调用方法,并且操作实例

非本地类型不可定义方法,也就是不可以给别的包的类型定义方法。

package main

import (
	"fmt"
)

type Stu struct {
	name string
	age  int
}

// 定义结构体Stu的方法
func (s *Stu) ShowInfo() {
	fmt.Printf("the user name is %v, age is %d\n", s.name, s.age)
}

func main() {
	s := Stu{"lucy", 18}
	s.ShowInfo() // the user name is lucy, age is 18
}

img

toString

在Java里面,实例的信息字符串一般由toString方法提供,在go里面,是由String() string函数提供,其原理也是实现了接口的方法

package main

import (
	"fmt"
)

type Stu struct {
	name string
	age  int
}

func (s Stu) String() string {
	return fmt.Sprintf("the user name is %v, age is %d\n", s.name, s.age)
}

func main() {
	s := Stu{"lucy", 18}
	fmt.Println(s)  // the user name is lucy, age is 18
	fmt.Println(&s) // the user name is lucy, age is 18
}

内嵌类型和结构体

内嵌类型

结构体可以包含一个或多个匿名(或内嵌)字段,即这些字段没有显式的名字,只有字段的类型是必须的,此时类型也就是字段的名字

package main

import "fmt"

type Stu struct {
	int
	string
}

func main() {
	s := Stu{18, "lucy"}
	fmt.Println(s.int, s.string) // 18 lucy
}

内嵌结构体(重要)

Go语言中的继承是通过内嵌或组合来实现的

同样地结构体也是一种数据类型,所以它也可以作为一个匿名字段来使用。内层结构体被简单的插入或者内嵌进外层结构体,外层结构体实例可以直接访问内嵌结构体成员。这个简单的“继承”机制提供了一种方式,使得可以从另外一个或一些类型继承部分或全部实现。

内嵌结构体可以对外层的结构体进行功能增强,外层结构体可以直接调用内层的方法

package main

import "fmt"

type Father struct {
	name string
	age  int
}
type Chil struct {
	id int
	Father
}

func main() {
	c := Chil{111, Father{"lucy", 18}}
	fmt.Printf("id:%d,name:%s,age:%d", c.id, c.name, c.age)
}

Go语言的结构体内嵌有如下特性:

toString

在java里面,实例的信息字符串一般由toString方法提供,在go里面,是由String() string函数提供,其原理也是实现了接口的方法

package main

import (
	"fmt"
)

type Stu struct {
	name string
	age  int
}

func (s Stu) String() string {
	return fmt.Sprintf("the user name is %v, age is %d\n", s.name, s.age)
}

func main() {
	s := Stu{"lucy", 18}
	fmt.Println(s)
	fmt.Println(&s)
}