[go]struct

结构体(打包多种类型的一种复合结构)

//struct类型(内存对齐)
// 结构体字段名类型相同,字段顺序不同, 占用的内存不同

//24bytes
type user struct {
	bool
	float64
	int16
}


//16bytes
type user struct {
	float64
	int16
	bool
}

在 Go 中恰到好处的内存对齐

//结构体元素: 占一块连续的内存地址空间
func main() {
	type test struct {
		a int8
		b int8
		c int8
	}
	n := test{
		1, 2, 3
	}
	fmt.Printf("n.a %p
", &n.a)
	fmt.Printf("n.b %p
", &n.b)
	fmt.Printf("n.c %p
", &n.c)
}

//n.a 0xc0000160c0
//n.b 0xc0000160c1
//n.c 0xc0000160c2
//type关键字: 给类型起别名(支持互相赋值)

func main() {
	type int2 = int
	var a int2
	fmt.Printf("%#v,%T", a, a)

	var b int
	b = a
	fmt.Printf("%#v,%T", b, b)
}

//0,int


//其他例子
type byte = uint8
type rune = int32
//type关键字: 定义一种新类型(不支持互相赋值)

func main() {
	type int2 int
	var a int2
	fmt.Printf("%#v,%T", a, a)

	var b int
	b = a
	fmt.Printf("%#v,%T", b, b)
}

//0,main.int2
//.main.go:11:4: cannot use a (type int2) as type int in assignment
//结构体: 多个不同类型命名字段, 打包成一个复合类型, 是值类型

//type关键字: 定义结构体
type User struct {
	name string
	age  int
}

1. 字段名必须唯一, 可用"_"
2. 字段名字,排列顺序属于类型的组成部分.
3. 支持使用自身指针类型成员
//实例化结构体: 仅声明, 字段值被零值填充

type User struct {
	name string
	age  int
}

func main() {
	var u User
	fmt.Printf("%T, %#v", u, u)
}

//main.User, main.User{name:"", age:0}

//实例化结构体: 无字段值, 字段值被零值填充
type User struct {
	name string
	age  int
}

func main() {
	u := User{}
	fmt.Printf("%T, %#v", u, u)
}

//main.User, main.User{name:"", age:0}
type User struct {
	name string
	age  int
}

func main() {
	u := User{}
	u.name = "mm"
	u.age = 22
	fmt.Printf("%T, %#v", u, u)
}

//main.User, main.User{name:"mm", age:22}
// 实例化结构体: 携带Field名
type User struct {
	name string
	age  int
}

func main() {
	u := User{
		name: "m1",
		age:  22,
	}
	fmt.Printf("%T, %#v", u, u)
}

//main.User, main.User{name:"m1", age:22}
// 实例化结构体: 不指定字段名(必须将所有字段值充全,缺一不可)
type User struct {
	name string
	age  int
}

func main() {
	u := User{"maotai", 12}
	fmt.Println(u)
}

//{maotai 12}
// 实例化结构体: 不指定字段名(必须将所有字段值充全,缺一不可)
type User struct {
	name string
	age  int
}

func main() {
	u := User{"maotai"}
	fmt.Println(u)
}

//.main.go:11:12: too few values in User literal
//实例化结构体: 携带Field名+给指定字段名赋值
type User struct {
	name string
	age  int
}

func main() {
	u := User{name: "mm"}
	u.age = 22
	fmt.Printf("%T, %#v", u, u)
}

//main.User, main.User{name:"mm", age:22}
//通过new进行实例化(返回该类型的地址)

type user struct {
	name string
	age  int
}

func main() {
	u := new(user)
	fmt.Printf("%T, %#v
", u, u) //*main.user &main.user{name:"", age:0}

	u.name = "m1"
	u.age = 22
	fmt.Printf("%#v
", u) //&main.user{name:"m1", age:22}
}
//*main.user, &main.user{name:"", age:0}
//&main.user{name:"m1", age:22}
// 取结构体的地址实例化
// u := new(user) 等价于 u := &user{}

type user struct {
	name string
	age  int
}

func main() {
	u := &user{}
	fmt.Printf("%T, %#v
", u, u) //*main.user &main.user{name:"", age:0}

	u.name = "m1" //go语言实现的语法糖 (*u).name = "m1"
	u.age = 22
	fmt.Printf("%#v
", u) //&main.user{name:"m1", age:22}
}
//*main.user, &main.user{name:"", age:0}
//&main.user{name:"m1", age:22}
//结构体构造函数(可使用goland快捷键一键生成这个函数)
type User struct {
	name string
	age  int
}

func NewUser(name string, age int) *User {
	return &User{name: name, age: age}
}
// 结构体字段标签

func main() {
	type user struct {
		name string `昵称`
		sex  byte   `性别`
	}

	u := user{"Tom", 1}

	v := reflect.ValueOf(u)
	fmt.Println(v.Field(0))            //Tom
	fmt.Println(v.Type().Field(0).Tag) //昵称
	fmt.Println(v.Type().NumField())   //2
}

匿名结构体

// 匿名结构体: 空结构体
func main() {
	var a struct{}
	fmt.Printf("%#v", a)
}

//struct {}{}
//匿名结构体声明: 初始化零值

func main() {
	var a struct {
		name string
		age  int
	}
	fmt.Printf("%#v",a)
}

//struct { name string; age int }{name:"", age:0}
//匿名结构体: 声明 初始化
func main() {
	var a struct {
		name string
		age  int
	}
	a = struct {
		name string
		age  int
	}{}
	fmt.Printf("%#v", a)
}

//struct { name string; age int }{name:"", age:0}
//匿名结构体: 声明+初始化
func main() {
	var a struct {
		name string
		age  int
	}
	a.name = "m1"
	a.age = 22
	fmt.Printf("%#v", a)
}

//struct { name string; age int }{name:"m1", age:22}
//匿名结构体: 1. 先声明 2.初始化
func main() {
	var a struct {
		name string
		age  int
	}
	a = struct {
		name string
		age  int
	}{name: "m1", age: 22}
	fmt.Printf("%#v", a)
}

//struct { name string; age int }{name:"m1", age:22}
//匿名结构体: 声明并初始化
func main() {
	a := struct {
		name string
		age  int
	}{name: "m1", age: 22}
	fmt.Printf("%#v", a)
}

//struct { name string; age int }{name:"m1", age:22}
//匿名结构体: 声明并初始化
func main() {
	a := struct {
		name string
		age  int
	}{}
	a.age = 22
	fmt.Printf("%#v", a)
}

//struct { name string; age int }{name:"", age:22}
//匿名结构体: 声明并初始化

func main() {
	a := struct {
		name string
		age  int
	}{"m1", 22}
	fmt.Printf("%#v", a)
}

//struct { name string; age int }{name:"m1", age:22}
// 匿名结构体作为字段类型

func main() {
	type file struct {
		name string
		attr struct {
			owner int
			perm  int
		}
	}
	f := file{
		name: "test.txt",
		attr: struct {
			owner int
			perm  int
		}{1, 1},
	}

	//f2 := file{
	//	name: "test.txt",
	//	attr: {  // 错误:missing type in composite literal
	//		owner int
	//		perm  int
	//	}{1, 1},
	//}

	f.attr.owner = 1
}

方法

//给任意类型绑定方法

type MyInt int

func (m *MyInt) incr() {
	*m++
}
func main() {
	var a MyInt
	a = 0
	a.incr()
	a.incr()
	fmt.Println(a)
}
//2

//给结构体绑定方法
type User struct {
	name string
	age  int
}

func (u User) get() {
	fmt.Println(u.name)
}

func (u *User) post() {
	u.name = "mm"
}

// 注: 指针接受者和值接收者
// 调用方法
type user struct {
	name string
	age  int
}

func (u *user) test() {
	fmt.Println("test func")
}

func main() {
	u := user{"m1", 22}
	u.test()   //值类型的调用实现指针类型调用效果, &u.test, go实现的语法糖
	(&u).test()
}
// 报错, 不支持多级指针调用
func main() {
	u := user{"m1", 22}

	(&u).test()
	(&((&u))).test()
}

继承

// 结构体的: 匿名字段, 不写字段名, 只有类型.  字段名就是类型名
type User struct {
	name string
	int
}

func main() {
	u:=User{
		name: "m1",
		int:  0,
	}

	fmt.Printf("%#v
", u)
}
//main.User{name:"m1", int:0}
type user struct {
	name string
	age  int
}
type manager struct {
	user         //字段名可省略
	title string
}

func main() {
	m := manager{
		user: user{
			name: "m1",
			age:  22,
		},
		title: "CTO",
	}
	fmt.Printf("%#v", m)
}

//main.manager{user:main.user{name:"m1", age:22}, title:"CTO"}
// 如嵌入其他包中的类型,实话时时, 隐式字段名字不包括包名。
type data struct{
   os.File
}

func main() {
   d:=data{
       File: os.File{},  //这里字段名不需要是os.File
    }

   fmt.Printf("%#v
",d)
}
//调用父类方法

type user struct {
	name string
	age  int
}

func (u *user) say() {
	fmt.Println("user say")
}

type manager struct {
	user
	title string
}

func main() {
	m := manager{}
	m.say()
}

//user say
//子类覆盖父类方法
type user struct {
	name string
	age  int
}

func (u *user) say() {
	fmt.Println("user say")
}

type manager struct {
	user
	title string
}
func (m *manager) say() {
	fmt.Println("manager say")
}

func main() {
	m := manager{}
	m.say()
	m.user.say()
}

//manager say
//user say
type data struct{ 
   sync.Mutex
   buf [1024]byte
} 
  
func main() { 
   d:=data{} 
   d.Lock()            // 编译会处理为sync.(*Mutex).Lock() 调用 
   defer d.Unlock() 
}
// 要求子类必须实现父类方法

type people interface {
	Init()
	Say()
}

type user struct {
}

func (u user) Init() {
	panic("implement me")
}

func (u user) Say() {
	panic("implement me")
}

type manager struct {
	user
}

func main() {
	var m manager
	m.Say()
}

//panic: implement me
原文地址:https://www.cnblogs.com/iiiiiher/p/11962149.html