Golang 结构体
结构体
Golang 中没有"类"的概念,Golang中的结构体和Java语言中的类有点相似,Golang结构体具有更高的扩展性和灵活性
Golang 中的基本数据类型可以装饰一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候单一基本属性就无法满足需求了,所有Golang 提供了一种自定义数据类型,可以封装多个基本数据类型,这种数据类型就叫结构体,英文struct。
type 关键字
Golang中通过type关键词定义了一个结构体,需要注意的是,数组和结构体都是值类型,和java是有区别的
自定义类型
在Go语言中有一些基本的数据类型,如string、整型、浮点型、布尔等数据类型,Go语言中可以使用type关键字来定义自定义类型。
package main
import "fmt"
func main() {
//定义myInt 类型
type myInt int
var a myInt = 10
fmt.Printf("%T,%v \n",a,a) // main.myInt,10
}
类型别名
Golang1.9版本以后添加的新功能
类型别名规定:TypeAlias 知识 Type的别名,本质上TypeAlias 和 type 是同一个类型。就像人小名 大名一样,实际上还是同一个人
type byte = uint8
type rune = int32
结构体定义和初始化
结构体定义
使用type 和 struct关键字来定义结构体,如下:
package main
import "fmt"
type Person struct {
name string
age int
sex string
}
func main() {
//第一种方式实例化
var person1 Person
person1.name = "weizhouck"
person1.age = 18
person1.sex = "男1"
fmt.Printf("%#v \n", person1) //main.Person{name:"weizhouck", age:18, sex:"男1"}
//第二种方式实例化-通过new关键字来实例化结构体,得到的是结构体的地址
var person2 = new(Person)
person2.name = "weizhouck"
person2.age = 18
person2.sex = "男2"
fmt.Printf("%#v \n", person2)//&main.Person{name:"weizhouck", age:18, sex:"男2"}
//第三种方式实例化-通过Person{}实例化结构体
var person3 = Person{}
person3.name = "weizhouck"
person3.age = 18
person3.sex = "男3"
fmt.Printf("%#v \n", person3)//main.Person{name:"weizhouck", age:18, sex:"男3"}
//第四种方式实例化-通过Person{}地址实例化结构体
var person4 = &Person{}
person4.name = "weizhouck"
person4.age = 18
person4.sex = "男4"
fmt.Printf("%#v \n", person4)//&main.Person{name:"weizhouck", age:18, sex:"男4"}
// 第五种方式初始化-使用键值对的方式来实例化结构体(key 可以省略)
var person5 = Person{
name: "张三",
age: 10,
}
fmt.Printf("%#v \n", person5)//main.Person{name:"张三", age:10, sex:""}
// 第五种方式初始化-key省略
var person6 = Person{
"张三",
10,
"男",
}
fmt.Printf("%#v \n", person6) //main.Person{name:"张三", age:10, sex:"男"}
}
结构体方法和接收者
在Go语言中,没有类的概念但是可以给类型(结构体、自定义类型)定义方法。所谓的方法就是定义了接收者的函数。
接收者的概念就是类似于java语言中的 this
方法的定义格式如下:
func (接收者变量 接收者类型) 方法名(参数列表)(返回参数) {
函数体
}
示例:
package main
import "fmt"
/**
* 定义结构体
*/
type Person struct {
name string
age int
sex string
}
/**
* 结构体方法
*/
func (p Person)PrintInfo(){
fmt.Print(" 姓名: ", p.name)
fmt.Print(" 年龄: ", p.age)
fmt.Print(" 性别: ", p.sex)
fmt.Println()
}
/**
* 因为结构体是值类型,所以我们修改的时候,因为是传入的指针
*/
func (p *Person)setInfo(name string,age int,sex string) {
p.name = name
p.age = age
p.sex = sex
}
func main() {
person := Person{
name: "weizhouck",
age: 18,
sex: "男",
}
person.PrintInfo() // 姓名: weizhouck 年龄: 18 性别: 男
person.setInfo("weizhou",19,"男")
person.PrintInfo() // 姓名: weizhou 年龄: 19 性别: 男
}
给任意类型添加方法
在Go语言中,接收者的类型可以是任何类型,不仅仅是结构体,任何类型都可以拥有方法。
举个例子,我们基于内置的int类型使用 type 关键字可以定义新的类型,然后添加打印方法
package main
import "fmt"
type myInt int
func (m myInt) PrintInfo() {
fmt.Println("我是自定义类型里面的自定义方法")
}
func main() {
var a myInt = 10
fmt.Printf("%v %T \n", a, a)
a.PrintInfo()
}
结构体的匿名字段
结构体允许其成员字段在声明时没有字段名而只有类型,这种没有名字的字段被称为匿名字段
匿名字段默认采用类型名作为字段名,结构体要求字段名称必须唯一,因此一个结构体中同类型的匿名字段只能一个
/**
定义一个人结构体
*/
type Person struct {
string
int
}
func main() {
// 结构体的匿名字段
var person = Person{
"张三",
18
}
}
结构体的字段类型可以是:基本数据类型,也可以是切片、Map 以及结构体
如果结构体的字段类似是:指针、slice、和 map 的零值都是nil,即还没有分配空间
如果需要使用这样的字段,需要先make,才能使用
package main
import "fmt"
type myInt int
func (m myInt) PrintInfo() {
fmt.Println("我是自定义类型里面的自定义方法")
}
/**
定义一个人结构体
*/
type Person2 struct {
name string
age int
hobby []string
mapValue map[string]string
}
func (p Person2) PrintInfo() {
fmt.Printf("%#v \n", p)
}
func main() {
person := Person2{}
person.PrintInfo()
person.name = "张三"
person.age = 10
// 给切片申请内存空间
person.hobby = make([]string, 4, 4)
person.hobby[0] = "睡觉"
person.hobby[1] = "吃饭"
person.hobby[2] = "打豆豆"
person.PrintInfo()
// 给map申请存储空间
person.mapValue = make(map[string]string)
person.mapValue["address"] = "北京"
person.mapValue["phone"] = "123456789"
// 加入#打印完整信息
person.PrintInfo()
}