结构体:就是根据基本类型造自己的类型,结构体占用一块连续的内存
定义结构体用大写还是小写?暂时用小写,如果用大写,别的包也能访问
自定义类型
type myInt int //自定义类型。type后面跟类型,用于给基本类型加方法
var n myInt = 100
fmt.Printf("%T", n) // main.myInt
// 给自定义类型加方法
// 不能给别的包里的类型添加方法,只能给自己包里的类型添加方法type myInt int
func (m myInt) hello() {
fmt.Println("我是一个int")
}m := myInt(100) // 100默认是int强转为myInt
m.hello()
自定义类型别名
type yourInt = int // 起别名。 编译后还是基本类型,只是在代码中给自己看的,例如rune,更直观
var n yourInt = 100
fmt.Printf("%T", n) // int
结构体模板:
type 类型名 struct {
字段名 字段类型
字段名 字段类型
…
}
类型名:标识自定义结构体的名称,在同一个包内不能重复。
字段名:表示结构体字段名。结构体中的字段名必须唯一。
字段类型:表示结构体字段的具体类型。没有默认值
值类型结构体
type person struct {
name string
age int
gender string
hobby []string
}
var p person //这样创建出来的是--p是值类型
p.name = "张三"
p.age = 12
p.gender = "男"
p.hobby = []string{"篮球","双色球"}
fmt.Printf("%T", p) //main.person
匿名结构体
var user struct{ Name string; Age int } // 匿名结构体,用于临时场景---user是值类型
user.Name = "小王子"
user.Age = 18
指针类型结构体
var p2 = new(person) //相当于var p2 person; &p2 。p2为结构体的地址
p2.name = "小王子" //可以对结构体指针直接使用"."来访问结构体的成员
p2.age = 28
p2.city = "上海"
或者这样创建(常用)
var p3 = &person{
name: "小王子"
age: 28
city: "上海"
}
或者这样创建
p4 := &person{
"小王子"
28
"上海"
}
构造函数: 返回一个结构体变量
问题:构造函数返回结构体?还是结构体指针?
当结构体字段较少可以返回结构体。 当结构体较大要使用指针,较少程序内存开销
注意:都是大写
func NewPerson(name string, age int) *Person {
return &Person{
Name: name
Nge: age
}
}
"方法"和"接收者"
// dog的结构体
type dog struct {
name string
}
// 构造函数
func newDog(name string) dog {
return dog{
name: name
}
}
// 这种作用于特定类型的函数才叫做"方法"
// 调用该方法的具体类型的变量叫"接收者",用类型首字母小写表示,比如此处的"d dog"的"d"
func (d dog) wang() { // 通过结构体调用的叫“方法” 通过包名直接调用的叫“ 函数 ”
fmt.Printf("%s:汪汪汪...", d.name)
}d1 := newDog("旺财")
d1.wang()
指针"接收者" vs 值"接收者"
func (d dog) wang()... //值"接收者",传的是拷贝
func (d *dog) wang()... //指针"接收者",传的是内存地址
什么时候用指针接收者?
- 要改接收者中的值
- 接收者是拷贝代价比较大的大对象
- 保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。
p是指针
fmt.Printf("%T", p) //打印p的类型 *int
fmt.Printf("%p", p) //打印p的值0x3423432