12-Go語言結構體

結構體

結構體的基本概念
  • 什么是結構體
    • 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[]}

    //切片和字典類型的必須要先初始化才可以使用
    //創(chuàng)建切片
    //per.sce = []int{10,20,30}
    //注意點: 使用索引方式,不能超過切片的長度
    per.sce = make([]int,3)
    per.sce[0]= 10
    per.sce[1]= 20
    per.sce[2]= 30


    //創(chuàng)建字典
    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屬性, 如果有就直接訪問
    //如果沒有會繼續(xù)查找嵌套的匿名結構體中有沒有, 如果有就訪問匿名結構體中的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)
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容