golang結構體

結構體是自定義的數據類型,表明一類事物,
結構體變量(實例)是具體的,實際的,表明一個具體變量程序員

type Cat struct {
    Name string
    Age int
    Color string
    Hobby string
}
func main() {
    var cat Cat
    cat.Name = "小黑"
    cat.Age = 34
    cat.Color = "黑色"
    cat.Hobby = "miao"
}

1、結構體變量內存佈局

結構體是值類型
image
在建立一個結構體變量後,若是沒有給字段賦值,都對應一個零值(默認值):
指針、slice和map的零值都是nil,即尚未分配空間golang

2、建立結構體實例的方式

  1. 方式一
var person Person
person.name = ""
person.age = 34
  1. 方式二
var person Person = {}
person.name = ""
person.age = 34
  1. 方式三
var person *Person = new(Person)
// p3是一個指針,也可person.name = "simon"
go設計者爲了簡化底層會加上取值符
(*person).name = "simon"
(*person).age = 34
  1. 方式四
var person *Person = &Person{}
// p3是一個指針
(*person).name = "simon"
(*person).age = 34
  • 建立結構體實例時,能夠直接指定字段的值
var stu1 Student = Student{"tom", 10}
stu2 := Student{"tom", 10}

// 指針變量
var stu3 *Student = &Student{"xiaomi", 14}

2、結構體使用細節

  • 結構體的全部字段在內存中是連續的
  • 結構體使用戶單獨定義的類型,和其餘類型進行轉換時須要徹底相同的字段(名字、個數、類型)
type A struct {
    Num int
}
type B struct {
    Num int
}
func main() {
   var a A
   var a B
   a = B(b) // 要強制轉換
}
  • 結構體的每一個字段上,能夠寫一個tag,該tag能夠經過反射機制獲取,常見場景序列化和反序列化
type Student struct {
    Name string `json:"name"`
    Age int `json:"age"`
}

3、結構體方法

golang中的方法是做用在指定的數據類型上的(即:和指定的數據類型綁定),所以自定義類型,都有方法,而不單單是structjson

type A struct {
    Num int
}

func (a A) test() {
    fmt.Println(a.Num)
}

func (a A) test() {} 表示A結構體有一個方法名,方法名爲test
(a A) 體現test方法是和A類型綁定的編輯器

  • 方法調用和傳參機制
  1. 在經過一個變量去調用方法時,其調用機制和函數同樣
  2. 不同的地方,變量調用方法時,該變量自己也會做爲一個參數傳遞到方法(若是變量是值類型,則進行值拷貝,若是變量是引用類型,則進行地址拷貝)
  • 方法注意事項和使用細節

若是程序員但願在方法中,修改結構體變量的值,能夠經過結構體指針的方式處理函數

type Circle struct {
    radius float64
}

func (c *Circle) area() float64 {
    // c 是指針, 訪問字段的方式是(*c).radius
    // (*c).radius 等價 c.radius
    return 3.14 * (*c).radius * (*c).radius
}
func main() {
    var c Circle
    c.radius = 5.0
    // 編輯器底層做了優化 (&c).area() 等價 c.area()
    res := (&c).area()
}

4、繼承

結構體可以使用嵌套匿名結構體全部的字段和方法,(首字母大小寫均可使用)佈局

type A struct {
    Name string
    age int
}

type B struct {
    A // 嵌套匿名結構體A,達到繼承
}

func (a *A) hello() {
    fmt.Println("你好")
}

func main() {
    var b B
    b.A.Name = "xiaoming"
    b.hello()
}

5、接口

interface類型默認是一個指針(引用類型),若是沒初始化就是用,會輸出nil。
空接口interface{},沒有任何方法,全部類型都實現了空接口,便可把任何類型變量賦值給空接口優化

type AInterface interface {
    test1()
}

type BInterface struct {
    test2()
}

type CInterface struct {
    AInterface // 繼承另外一個接口
    BInterface
    test3()
}

type Stu struct {

}

func (stu Stu) test1() {

}

func (stu Stu) test2() {
    
}

func (stu Stu) test3() {
    
}

func main() {
    var stu Stu
    var a AInterface = stu
    a.test1()
}

6、斷言

因爲接口是通常類型,不知道具體類型,若是要轉成具體類型,就須要使用類型斷言spa

func main() {
    var t float32
    var x interface{}
    x = t
    y, ok := x.(float32) // 轉成float32
    if ok == true {
        fmt.Println("convert success")
    } else {
        fmt.Println("convert fail")
    }
}
相關文章
相關標籤/搜索