美文网首页
12-Go语言结构体

12-Go语言结构体

作者: 喝酸奶要舔盖__ | 来源:发表于2018-09-26 15:57 被阅读0次

结构体

结构体的基本概念
  • 什么是结构体
    • Go语言中的结构体几乎和C语言中的结构体一模一样都需要先定义结构体类型, 再定义结构体变量都是用来保存一组不同类型数据的
    • 定义结构体类型格式:
      type 结构体类型名称 struct{
      属性名称 属性类型;
      属性名称 属性类型;
      }
    • 定义结构体变量格式: var 结构体变量名称 结构体类型名称

结构体初始化

注意点: 和切片以及字典不一样, 结构体变量定义之后就可以直接使用了

//1.定义一个结构体
    //1.1定义结构体类型
    type Person struct {
        name string
        age int
    }
    //1.2定义结构体变量(先定义后初始化)
    var per Person
    //1.3操作结构体
    //切片和字典定义变量后必须初始化才能使用
    //结构体变量定义完成后不需要初始化可以直接使用
    per.name = "lnj"
    per.age = 18
    fmt.Println(per)
  • 先定义结构体变量再初始化
//3.先定义结构体变量再初始化
    //定义结构体类型
    type Person struct {
        name string
        age int
    }
    //定义结构体变量
    var per Person
    //给结构体完全初始化
    per = Person{"wjh",19}
    //给结构体部分初始化
    //注意点: 部分初始化必须通过属性名称指定要给谁初始化
    per = Person{age : 18}
    fmt.Println(per)
  • 定义结构体变量的同时初始化
//2.定义结构体变量一次性初始化
    //定义一个结构体类型
    type Person struct {
        name string
        age int
    }
    //定义结构体变量一次性初始化
    var per Person = Person{"lnj",18}
    //结构体变量名称后面可以省略结构体类型
    var per = Person{"lnj",18}
    //可以使用语法糖来定义同时一次性初始化
    per := Person{"lnj",18}
    fmt.Println(per)

结构体值传递
package main

import "fmt"

//定义一个结构体
type Person struct {
    name string
    age int
}
func main() {
    /*
    结构体和数组一样,都是值传递
    作为函数的参数,在函数内部修改值不会影响到外面实参的值
    */

    per1 := Person{"wjh", 19}
    var per2 Person
    //将结构体变量per1的值传递给per2
    per2 = per1
    per2.name = "lnj"
    fmt.Println(per1)//{wjh 19}
    //修改结构体变量per2的值不会影响per1中的值
    fmt.Println(per2)//{lnj 19}

    per := Person{"lnj", 10}
    //结构体作为函数的参数,在函数内部修改值不会影响到外面实参的值
    change(per)
    fmt.Println(per)

}
func change(per Person)  {
    per.name = "haha"
}

复杂结构体
package main

import "fmt"

func main() {
    /*
    复杂的结构体
    */

    type Person struct {
        name string //字符串
        age int  //整型
        score float64 //浮点型
        arr [3]int //数组类型
        sce []int //切片类型
        dict map[string]string  //字典类型
    }

    //普通类型结构体属性都可以直接操作,不需要初始化
    var per Person
    per.name = "lnj"
    per.age = 18
    per.score = 80.5
    per.arr[0] = 10
    per.arr[1] = 20
    per.arr[2] = 30

    //{lnj 18 80.5 [10 20 30] [] map[]}

    //切片和字典类型的必须要先初始化才可以使用
    //创建切片
    //per.sce = []int{10,20,30}
    //注意点: 使用索引方式,不能超过切片的长度
    per.sce = make([]int,3)
    per.sce[0]= 10
    per.sce[1]= 20
    per.sce[2]= 30


    //创建字典
    per.dict = make(map[string]string,2)
    per.dict["name"] = "wjh"
    per.dict["age"] = "18"
    //per.dict = map[string]string{"name":"wjh","age" :"18"}
    fmt.Println(per)
}


结构体转换

注意点:结构体变量之间可以相互转换, 但是必须保证结构体类型的属性名称 属性类型 属性顺序 属性的个数 都一样

package main

import "fmt"

func main() {
    /*
    结构体变量之间可以相互转换, 但是必须保证结构体类型的
    属性名称 属性类型 属性顺序 属性的个数 都一样
    */

    type Person1 struct {
        name string
        age int
    }

    //属性顺序不同
    type Person2 struct {
        age int
        name string
    }
    //属性名称不同
    type Person3 struct {
        name string
        score int
    }
    //属性类型不同
    type Person4 struct {
        name string
        score float64
    }
    //属性的个数不同
    type Person5 struct {
        name string
        age int
        score float64
    }

    //属性顺序不同不能强转
    //var per2 Person2
    //per2 = Person1(per2)
    //fmt.Println(per2)


    //属性名称不同不能强转
    //var per3 Person3
    //per3 = Person1(per3)
    //fmt.Println(per3)

    //属性类型不同不能强转
    var per4 Person4
    per4 = Person1(per4)
    fmt.Println(per4)

    //属性个数不同不能强转
    var per5 Person5
    per5 = Person1(per5)
    fmt.Println(per5)
}


匿名结构体
  • 什么是匿名结构体属性?
    没有名称的属性就是匿名属性
  • 如何操作匿名属性?
    匿名属性的数据类型就是匿名属性的名称, 所以可以通过匿名属性的数据类型来操作
  • 匿名属性一般都用于结构体的嵌套定义,结构体的属性又是一个结构体
package main

import "fmt"

func main() {
    type Person struct {
        string //匿名结构体属性
        int
    }

    var per Person
    per.string = "wjh" //可以通过匿名属性的数据类型来操作
    per.int = 18
    fmt.Println(per)

    type Date struct {
        year int
        month int
        day int
    }

    type Person struct {
        name string
        age int
        Date //结构体嵌套定义

    }

    type Animal struct {
        name string
        age int
        Date
    }

    //使用结构体嵌套
    var per Person
    per.name = "wjh"
    per.age = 19
    per.Date = Date{2007,10,23} //{wjh 19 {2007 10 23}}
    fmt.Println(per)

    //定义结构体变量同时直接初始化
    ani := Animal{"wawa",10,Date{2003,10,23}}
    fmt.Println(ani)//{wawa 10 {2003 10 23}}
}

结构体嵌套的方式
  • 第一种方式(双重嵌套)
    type 结构体名称1 struct{

    }
    type 结构体名称2 struct{
    结构体名称1
    }

//1.第一种方式
    // 结构体和嵌套的结构体没有重名属性的情况
    type Person struct {
        name string
        age int
    }

    type Student struct {
        Person
        score float64
    }

    //定义同时初始化结构体
    stu := Student{Person{"wjh", 19}, 86.6}
    fmt.Println(stu)

    ////1.1结构体嵌套定义,第一种操作结构体方法
    //stu.Person.name = "lnj"
    //stu.Person.age = 30
    //fmt.Println(stu)

    //1.2第二种操作结构体方法
    //会先去Student结构体中查询有没有name属性, 如果有就直接访问
    //如果没有会继续查找嵌套的匿名结构体中有没有, 如果有就访问匿名结构体中的name属性
    stu.name = "zs" //嵌套结构体属性不重名可以直接访问
    stu.age = 20
    fmt.Println(stu)
    //2.第一种方式有重名属性的情况
    //结构体和嵌套的结构体有重名属性的情况
    type Person struct {
        name string
        age int
    }

    type Student struct {
        Person
        name string
        score float64
    }

    //定义同时初始化结构体
    stu := Student{Person{"wjh",19},"lnj", 90.3}
    fmt.Println(stu) //{{wjh 19} lnj 90.3}

    //2.1结构体嵌套定义,操作结构体的第一种方法
    //注意点: 如果结构体与嵌套的结构体属性有重名,使用这种方法操作数据,不会更改嵌套结构体中的同名属性
    stu.name = "haha"
    fmt.Println(stu) //{{wjh 19} haha 90.3}

    //2.2结构体嵌套定义,操作结构体第二种方法
    //注意点: 如果结构体与嵌套的结构体属性有重名,应该先指定结构体类型在指定结构体属性
    stu.Person.name = "zs"
    stu.age = 30
    fmt.Println(stu) //{{zs 30} haha 90.3}
  • 第二种方式(三重嵌套)
    type 结构体名称1 struct{
    }
    type 结构体名称2 struct{
    结构体名称1
    }
    type 结构体名称3 struct{
    结构体名称2
    }
//第二种方式
    //1.没有重名属性
    type Object struct {
        name string
    }
    type Person struct {
        Object
        age int
    }
    type Student struct {
        Person
        score float32
    }

    //定义变量同时初始化
    stu := Student{Person{Object{"wjh"}, 19}, 87.3}
    fmt.Println(stu) //{{{wjh} 19} 87.3}

    //操作结构体第一种方法
    stu.name = "zs"
    stu.age = 30
    stu.score = 50.3
    fmt.Println(stu) //{{{zs} 30} 50.3}

    //操作结构体第二种方法
    stu.Person.Object.name = "lnj"
    stu.Person.age = 50
    fmt.Println(stu) //{{{lnj} 50} 50.3}
//有重名属性的情况
    type Object struct {
        name string
    }
    type Person struct {
        Object
        name string
        age int
    }
    type Student struct {
        Person
        name string
        score float32
    }

    //定义变量同时初始化
    stu := Student{Person{Object{"wjh"},"lnj",13},"niuzi",39.2}
    fmt.Println(stu) //{{{wjh} lnj 13} niuzi 39.2}

    //操作结构体方法
    //注意点: 如果不先指定结构体类型,只会操作最外面结构体的对应的重名属性
    stu.name = "whaha" //修改Student结构体类型的name属性
    stu.Person.name = "zs"  //修改Person结构体类型的name属性
    stu.Person.Object.name = "lili"  //修改Object结构体类型的name属性
    fmt.Println(stu) //{{{lili} zs 13} whaha 39.2}
    
  • 第三种方式
    type 结构体名称1 struct{

    }
    type 结构体名称2 struct{
    }
    type 结构体名称3 struct{
    结构体名称1
    结构体名称2
    }

//第三种方式
    //没有重名属性情况
    type Object struct {
        name string
    }
    type Person struct {
        age int
    }
    type Student struct {
        Object
        Person
        score float64
    }

    //定义变量同时初始化
    stu := Student{Object{"lnj"},Person{19},30.6}
    fmt.Println(stu) //{{lnj} {19} 30.6}

    //操作结构体属性
    stu.Person.age = 30
    stu.Object.name = "wjh"
    fmt.Println(stu) //{{wjh} {30} 30.6}
    

    //有重名属性的情况
    type Object struct {
        name string
    }
    type Person struct {
        name string
        age int

    }
    type Student struct {
        Object
        Person
        name string
        score float64
    }

    stu := Student{Object{"haha"},Person{"lnj", 19},"wjh", 30.5}
    fmt.Println(stu)

    //操作结构体属性
    stu.name = "ll"
    stu.Person.name = "zz"
    stu.Object.name = "kk"
    fmt.Println(stu)

结构体嵌套定义注意点
  • 结构体的属性类型不能是当前结构体的类型(不能自己嵌套自己)
  • 只有匿名属性才会向上查找, 非匿名属性不会向上查找
package main

import "fmt"

func main() {
    /*
    1.结构体的嵌套定义的注意点:
    1.1结构体的属性类型不能是当前结构体的类型
    1.2只有匿名属性才会向上查找, 非匿名属性不会向上查找
    */

    type Person struct {
        //Person  结构体属性不能是自己本身的结构体类型
        name string
        age  int
    }

    type Student struct {
        //per Person //非匿名结构体属性
        Person //匿名结构体属性
        score float32
    }

    stu := Student{Person{"wjh", 18}, 52.3}
    fmt.Println(stu)
    //匿名结构体属性会自动往匿名结构体查找属性
    //非匿名结构体属性使用这种方法查找会报错
    fmt.Println(stu.name)
    fmt.Println(stu.age)
}

相关文章

  • 12-Go语言结构体

    结构体 结构体的基本概念 什么是结构体Go语言中的结构体几乎和C语言中的结构体一模一样都需要先定义结构体类型, 再...

  • 12-Go语言字典和结构体-指趣学院

    map(字典、映射) map翻译过来就是字典或者映射, 可以把map看做是切片的升级版切片是用来存储一组相同类型的...

  • C语言和OC的结构体(struct)

    Struct(结构体) 1.结构体定义 2.结构体变量 3.结构体数组 4.C语言结构体指针 5.C语言共用体 6...

  • Golang 学习笔记四 结构体

    一、结构体 《快学 Go 语言》第 8 课 —— 结构体1.结构体类型的定义结构体和其它高级语言里的「类」比较类似...

  • 结构体

    结构体初识 结构体指针 结构体的匿名字段 结构体嵌套 Go语言中的OOP

  • 13-GoLang结构体

    结构体 Go语言中的结构体几乎和C语言中的结构体一模一样都需要先定义结构体类型, 再定义结构体变量都是用来保存一组...

  • 嵌入式学习笔记19.11.25

    c语言结构体 结构体一般定义全局变量 struct stu{//struct 定义结构体 stu 结构体名称 in...

  • Tank技术【3-6】GoLang语法实战学习(4)

    九、结构体 Go语言的结构体和C语言是类似的。定义结构体如下: 使用结构体有两种办法: 后两个是直接用:=赋值来声...

  • C语言 13 结构体数组

    C语言 13 结构体数组 结构体数组的定义 结构体数组初始化 结构体成员的使用 格式 : 字符串成员的处理 结构体...

  • C语言20 结构体指针

    C语言20 结构体指针 探测结构体指针的特性 ++、-- 加法与减法 指针相减 使用结构体指针 结构体指针一定要指...

网友评论

      本文标题:12-Go语言结构体

      本文链接:https://www.haomeiwen.com/subject/kgtjoftx.html