golang结构体struct学习笔记

结构体struct
  1. Go中的struct与C中的struct非常相似,并且Go没有class
  2. 使用type<Name>struct{}定义结构,名称遵循可见性规则
  3. 支持指向自身的指针类型成员
  4. 支持匿名结构,可用作成员或定义成员变量
  5. 匿名结构也可以用于map的值
  6. 可以使用字面值对结构进行初始化
  7. 允许直接通过指针来读写结构成员
  8. 相同类型的成员可进行直接拷贝赋值
  9. 支持 ==!=比较运算符,但不支持><
  10. 支持匿名字段,本质上是定义了以某个类型名为名称的字段
  11. 嵌入结构作为匿名字段看起来像继承,但不是继承
  12. 可以使用匿名字段指针
  13. 在函数,属于值拷贝,如果要改原值,需要修改指针。
    “`
    type person struct{
    name string
    age int
    }
    func A(per *person){
    per.age = 13
    }

如果需要改的次数过多,需要先取指针(推荐)

        a := &person{
            name :"Joe",
            age:19,
        }
        a.name = "xiaoming" //直接操作指针就可以

        A(a)
        B(a)

        func A(per *person){
            per.age = 13
        }

        func B(per *person){
            per.age = 15
        }
  1. 基本使用
   type person struct{
    Name string
    Age int
   }
   func main(){
    a:= person{
        Name:"Joe"
    }
    a.Age = 19
    fmt.Println(a)
   }
  1. 匿名结构
   func main(){
    // a := struct{
    a := &struct{
        name string
        age int
    }{
        name:"xiaoming",
        age:19,
    }

    fmt.Println(a)
   }
  1. 嵌套匿名结构体
   type person struct{
    name string
    age int
    contact struct{
        phone, city string
    }
   }

   func main(){
    a := person{name:"joe",age:19}
    a.contact.phone = "122332"  // 只能这样赋值
    a.contact.city = "beijing"
    fmt.Println(a)
   }
  1. 匿名字段
   type person struct{
    string
    int
   }
   func main(){
    a := person{"joe",19}   // 顺序不能出错
    fmt.Println(a)
   }
  1. 继承

    type human struct{
        sex int
    }
    type teacher struct{
        human
        name string
        age int
    }
    type student struct{
        human 
        name string
        age int
    }
    
    func main(){
        a := teacher{name:"han",age:12,human:human{sex:1}}
        b := student{name:"zhang",age:19,human:human{sex:0}}
        a.name = "joe"
        a.age = 13
        a.sex = 100
        fmt.Println(a)
    }
    
  2. 内外层有同名属性

    type person struct{
        name string
        age int
    }
    type student struct{
        person
        name string
        age int
    }
    
    func main(){
        a := student{name:"zhangsan",age:12,person:person{name:"lisi",age:20}}
        fmt.Println(a.name)  // zhangsan
        fmt.Println(a.person.name)  //lisi
    }
    
    // 嵌入级别大于1个的时候 ,不允许有同名属性,否则编译报错

Struct

type person struct{
    name string
    age int
}
  1. 使用:

    var P person || P := {"Tom",25} || P := {age:24,name:"Tom"}
    P.name = "xiaoming"
    P.age = 12
    fmt.Println(P)
    
    r1 := new(Rect)
    r2 := &Rect{}
    r3 := &Rect{0,0,100,200}
    r4 := &Rect{width:100,height:200}
    

还有其他几种声明使用方式
1. 按照顺序提供初始化值
P := person{“Tom”,25}
2. 通过 field:value 的方式初始化,这样可以任意顺序
P := person{age:24,name:”Tom”}
3. 当然也可以通过new函数分配一个指针,此处P的类型为 *person
P := new(person)

  1. 匿名字段

    type Human struct {
        name string
        age int
        weight int
    }
    
    type Student struct {
        Human  // 匿名字段,那么默认Student就包含了Human的所有字段
        speciality string
    }
    
  2. 方法(method)
    func (r ReceiverType) funcName(parameters)(results)

    func (r Rectangle) area() float64{
        return r.width*r.height
    }
    

方法

  1. Go中虽然没有class,但依旧有method
  2. 通过显示说明receiver来实现与某个类型的组合
  3. 只能为同一个包中的类型定义方法
  4. Receiver可以是类型的值或指针
  5. 不存在方法重载
  6. 可以使用值或指针来调用方法,编译器会自动完成转换
  7. 从某种意义上来说,方法是函数的语法糖,因为receiver其实就是方法所接收的第1个参数
  8. 如果外部结构和嵌入结构存在同名方法,则优先调用外部结构的方法
  9. 类型别名不会拥有底层类型所附带的方法
  10. 方法可以调用结构中的非公开字段
  1. 使用
   type person struct {
        name string
        sex int
   }
   func (p person)sayHello(){   //(p是参数,person是接收者的类型)
        fmt.Println("我是person")
   }

   func main()  {
        a := person{}
        a.sayHello()
   }
  1. 方法里面改变结构体的属性 -> 传递指针
   type A struct{
        name string
   }
   func main(){
        a := A{}
        a.Print()
        fmt.Println(a.name)
   }

   func(a *A)Print(){
        a.name = "aa"
        fmt.Println("A")
   }
  1. 底层类型的结构定制(只有当前包中有效)
   type TZ int
   func main(){
        var a TZ
        a.Print()
   }

   func (a *TZ)Print(){
        fmt.Println("TZ")
   }
  1. method expression -> 直接通过类型调用,而不用通过变量来调用
   type TZ int
   func main(){
        var a TZ
        a.Print()  // method value 通过变量来调用方法
        (*TZ).Print(&a)  // (*TZ)是receiver,&a是变量
   }

   func (a *TZ)Print(){
        fmt.Println("TZ")
   }
  1. method冲突,和struct一样
  2. 通过method修改变量的值
   type TZ int
   func main(){
        var a TZ
        fmt.Println(a)
        a.AutoAdd()
        fmt.Println(a)
   }
   func (tz *TZ)AutoAdd(){
        *tz += 100
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值