go 結構體 (struct) 和方法 (method)

結構體(struct)

go中沒有對象這一律念,因此採用告終構體的概念,結構體在go中有着很是重要的位置。結構體是值類型,因此可使用new函數來建立。結構體中字段必須惟一。微信

結構體定義以下:ide

type identifier struct {
    filed type
    filed type
}
複製代碼

filed就是結構體的字段名字,type是字段的類型,若是暫時不知道命名,可使用 _ 來進行佔位。字段可使用任何類型,甚至是結構體自己,也能夠是函數或者接口。 通常來講,給結構體的字段賦值這樣便可:函數

var s T
s.a = 1
s.b = 2
複製代碼

使用new函數給一個新的結構體變量分配內存,返回已分配內存:ui

var t *T = new(T)
// or
t := new(T)
複製代碼

例子:spa

type Person struct {
    Name string
    Age  int
    Sex  int
}

func main() {
    person := new(Person)
    person.Name = "Tim"
    person.Age  = 10
    person.Sex  = 1
    
    //or
    
    person := &Person{"Tim", 10 , 1}
    
    fmt.Println(person)
}

// 輸出 &{Tim, 10, 1}

複製代碼

就像面嚮對象語言那樣,可使用點來給字段進行賦值,一樣的也能夠經過點來進行獲取字段的值。指針

結構體一樣能夠做爲參數進行傳遞:code

func getPersonName(p *Person) string {
    return p.Name
}

func main() {
    ...
    
    fmt.Prinltn(getPersonName(person))
}
// 輸出 Tim
複製代碼

若是想知道一個結構體佔用了多少內存,可使用:cdn

size := unsafe.Sizeof(T{}}
複製代碼

結構體中除了字段和類型外,還有一個可選的標籤,一個字段的輔助字符串,只有reflect能獲取它。對象

例子:索引

type Person struct {
    Name string "Name"
    Age  int    "Age"
    Sex  int    "Sex"
}

func main() {
    person := Person{}
    person.Name = "Tim"
    person.Age  = 10
    person.Sex  = 1
    
    for i := 0; i < 3; i++ {
        refTag(person, i)
    }
}

func refTag(p Person, i int) {
    pType := reflect.TypeOf(p)
    iFiled := pType.Filed(i)
    fmt.Println(iFiled.Tag)
}

//out 
複製代碼

reflect.TypeOf能夠獲取變量的正確類型,若是變量是一個結構體,就能夠經過Filed來索引該結構體的字段,而後就可使用Tag屬性。

go結構體還支持一個特殊字段,匿名字段。這些字段沒有顯式的名字,只有字段類型,此時字段類型也就是字段的名字,匿名字段也能夠是一種結構體。

例子:

type Test1 struct {
    t1 int
    t2 int
}

type Test struct {
    a int
    b string
    bool
    Test1
}

func main() {
    test := new(Test)
    test.a = 1
    test.b = "2"
    test.bool = true
    test.t1 = 2
    test.t2 = 3
    
    fmt.Println(test)
}

//out &{1, "2", true, 2, 3}
複製代碼

經過test.bool的名字來獲取匿名字段的數據,因而能夠得出一個結論,在一個結構體中對於每一種數據類型只能有一個匿名字段。 在結構體內嵌結構體是,若是遇到命名衝突可是又都須要保留時,可使用:

Test.Test1.Filed
複製代碼

這樣使用就避免了命名衝突。

方法

go方法是做用在接收者上的一個函數,接收者是某種類型的變量,所以方法是一種類型的函數。接收者類型幾乎能夠任何類型,指針類型和函數類型就不行。 由於方法是函數,因此方法不能被重載,對於一個類型只有一個既定名稱的方法。 定義方法的格式以下:

func (r receiver_type) methodName(parmeter_list) (value_list){
    ...
}
複製代碼

r是receiver_type的實例,methodName是r的方法名,調用也很簡單,r.methodName() 便可。 例子:

type Person struct {
    Name string
    Age  int
}

func (p *Person) GetName() string {
    return p.Name
}

func (p *Person) GetAge() int {
    return p.Age
}

func main() {
    p := new(Person)
    p.Name = "1"
    p.Age  = 2
    
    fmt.Prinltn(p.GetName())
    fmt.Prinltn(p.GetAge())
}

// out "1" 2
複製代碼

微信搜索「goentry-xyz」,關注公衆號「燈下獨碼」

相關文章
相關標籤/搜索