美文网首页
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语言结构体

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