go_day4 结构体和方法

type后面接的都是类型
自定义类型和别名

package main

import "fmt"

type myint int    //自定义类型,编译完还保留
type tmpint = int //类型别名,只在代码编写时有效

func main() {
	var x myint = 10
	fmt.Println(x)
	fmt.Printf("%T\n", x)
	var y tmpint = 20
	fmt.Println(y)
	fmt.Printf("%T\n", y)
	//rune就是int32的类型别名
	//告诉别人这是一个字符,不是一个数
}

结构体也是用type来定义,类型是package_name.struct_name

package main

import "fmt"

type student struct {
	name   string
	age    int
	gender rune
	hobby  []string
}

func main() {
	// 声明一个student类
	var ydssx student
	// 通过字段赋值
	ydssx.age = 18
	ydssx.name = "夜刀神十香"
	ydssx.gender = '女'
	ydssx.hobby = []string{"打怪", "摸鱼"}
	fmt.Println(ydssx)
	fmt.Printf("%c", ydssx.gender)
}

匿名结构体,不用写type和name

package main

import "fmt"

func main() {
	// 定义匿名结构体
	var x struct {
		a string
		b int
	}
	x.a = "777"
	x.b = 777
	fmt.Printf("%T %v", x, x)
}
//struct { a string; b int } {777 777}

结构体本身属于值类型
创建结构体的四种方式
1.像变量一样创建,一一赋值
2.像创建多个变量一样,变量列表复制
3.在2的基础上省略掉键
4.使用new来创建,此时创建的是结构体指针
如果想通过前面的方法来创建结构体指针,只需要使用&取地址就好。
所以结构体基本就可以看作是普通的数据类型,就是赋值方式有三种
其中结构体指针可以直接使用.来进行赋值,这是go中的语法糖

package main

import "fmt"

type people struct {
	name int
	id   string
}

func main() {
	var a people
	a.id = "11"
	a.name = 0
	// var a *int = new(int)
	// *a = 10
	// fmt.Printf("%p %v", a, *a)
	// 结构体指针1
	var b *people = new(people)
	b.id = "777"
	(*b).name = 1
	fmt.Println(b)
	fmt.Println(*b)
	fmt.Printf("%T\n", b)
	fmt.Printf("%p\n", &b)
	fmt.Printf("%p\n", b)
	fmt.Printf("%v\n", b)
	// 结构体指针2
	// key-value 初始化

	//var c = &people{···} 就是指针了,这种方式较为常用
	var c = people{
		id:   "777",
		name: 2,
	}
	fmt.Println(c)
	// 使用值列表进行初始化,值的顺序要与结构体定义字段顺序一致
	d := people{
		3,
		"555",
	}
	fmt.Println(d)
/*
{0 11}
&{1 777}
{1 777}
*main.people
0xc000006030
0xc000004090
&{1 777}
{2 777}
{3 555}
*/
}

结构体内部字段是连续的,即结构体占用一块连续的内存地址

package main

import "fmt"

type people struct {
	name int8
	id   int8
}

func main() {
	var a people
	a.id = 1
	a.name = 0
	fmt.Println(&a.id)
	//0xc0000140a9
	fmt.Println(&a.name)
	//0xc0000140a8
}
如果数据类型不一样,可能会出现内存对齐

go语言的构造函数约定俗称用new开头

package main

import "fmt"

type people struct {
	name int8
	id   int8
}

func newPeople(name int8, id int8) *people {
	return &people{
		name: name,
		id:   id,
	}
}
func main() {
	fmt.Println(*newPeople(1, 2))
}
// {1 2}

结构体构造函数返回的是结构体还是结构体指针:
当结构体比较大的时候尽量使用结构体指针,减少程序的内存开销

方法和接收者
方法中的接收者只能写一个

package main

import "fmt"
// 结构体定义
type dog struct{
	name string
}
// 构造函数
func newDog(name string) dog{
	return dog{
		name: name,
	}
}
// 方法是作用于特定类型的函数
// 接收者表示的是调用该方法的具体类型变量,多用类型名首字母小写表示
func (d dog)bark(){
	fmt.Printf("%v www\n",d.name)
}

func main(){
	d1:=newDog("a")
	d1.bark()	

}

不能给别的包里面的类型添加方法,只能给自己的包里添加方法
比如要给int添加方法,需要使用type myint int自定义类型的方式来给myint添加。
标识符:变量名 函数名 类型名 方法名
Go中如果标识符首字母是大写,就表示对外部可见(外部的,公有的)

上一篇:1336:【例3-1】找树根和孩子


下一篇:050.函数-函数的调用