zoukankan      html  css  js  c++  java
  • [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
    
  • 相关阅读:
    PHP配置redis支持
    redis入门——redis常用命令
    CentOS7 linux下yum安装redis以及使用
    Linux安装配置git
    Java基础88 数据库设计的三大范式
    Java基础87 MySQL数据约束
    Java基础85 MVC开发模式
    错误/异常:java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind;的解决方法
    Java基础84 javaBean规范
    Java基础83 JSP标签及jsp自定义标签(网页知识)
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/11962149.html
Copyright © 2011-2022 走看看