Golang:結構體

結構體

結構體(struct)是用戶自定義的類型,代表若干字段的集合。有時將多個數據看做一個整體要比單獨使用這些數據更有意義,在這種情況下就適合使用結構體。

比如將一個員工的 firstName, lastName 和 age 打包在一起成為一個結構體就是很有意義的。

具名結構體
type Employee struct {
    firstName, lastName string
    age                 int
}

上面的 Employee 是一個具名結構體(named structure),因為它創建了一個具有名字的結構體類型: Employee 。

匿名結構體

我們也可以定義一個沒有類型名稱的結構體,這種結構體叫做匿名結構體(anonymous structures)。

var employee struct {  
        firstName, lastName string
        age                 int
}

上面的代碼片段聲明了一個匿名結構體變量 employee。

package main

import (
    "fmt"
)

func main() {
    var emp1 struct {
        firstName, lastName string
        age                 int
    }
    emp1.firstName = "Andreah"
    emp1.lastName = "Nikola"
    emp1.age = 31

    emp2 := struct {
        firstName, lastName string
        age                 int
    }{
        firstName: "Andreah",
        lastName:  "Nikola",
        age:       31,
    }
    fmt.Println("Employee 1", emp1)
    fmt.Println("Employee 2", emp2)
}
匿名字段

定義結構體類型時可以僅指定字段類型而不指定字段名字。這種字段叫做匿名字段(anonymous field)。

package main

import (
    "fmt"
)

type Person struct {
    string
    int
}

func main() {
    p := Person{"Naveen", 50}
    fmt.Println(p)
}

在上面的程序中,Person 是一個具有兩個匿名字段的結構體類型,類型分別為 stringint

雖然匿名字段沒有名字,但是匿名字段的默認名字為類型名。比如上面的 Person 類型,盡管它的字段是匿名的,但是默認它們擁有它們的類型的名字。因此 Person 結構體有兩個名為 string 和 int 的字段。

package main

import (
    "fmt"
)

type Person struct {
    string
    int
}

func main() {
    var p1 Person
    p1.string = "naveen"
    p1.int = 50
    fmt.Println(p1)
}

在上面的程序中,我們通過使用匿名字段的類型名("string""int")來訪問 Person 結構體的字段。

導出結構體和字段

如果一個結構體類型的名稱以大寫字母開頭,則該結構體被導出,其他包可以訪問它。同樣地,如果結構體中的字段名以大寫字母開頭,則這些字段也可以被其他包訪問。

type Spec struct { //exported struct
    Maker string //exported field
    model string //unexported field
    Price int    //exported field
}
比較結構體

結構體是值類型,如果其字段是可比較的,則該結構體就是可以比較的。如果兩個結構體變量的所有非空字段都相等,則認為這兩個結構體變量相等。

package main

import (
    "fmt"
)

type name struct {
    firstName string
    lastName  string
}

func main() {
    name1 := name{"Steve", "Jobs"}
    name2 := name{"Steve", "Jobs"}
    if name1 == name2 {
        fmt.Println("name1 and name2 are equal")
    } else {
        fmt.Println("name1 and name2 are not equal")
    }

    name3 := name{firstName: "Steve", lastName: "Jobs"}
    name4 := name{}
    name4.firstName = "Steve"
    if name3 == name4 {
        fmt.Println("name3 and name4 are equal")
    } else {
        fmt.Println("name3 and name4 are not equal")
    }
}

在上面的程序中,name 結構體類型包含兩個 string 字段。因為 string 是可比較的,因此兩個 name 類型的變量也是可以比較的。所以,name1 和 name2 是相等的,而 name3 和 name4 是不相等的。

如果結構體包含不可比較的類型的字段,那么這兩個結構體是不可比較的。

package main

import (
    "fmt"
)

type image struct {
    data map[int]int
}

func main() {
    image1 := image{data: map[int]int{
        0: 155,
    }}
    image2 := image{data: map[int]int{
        0: 155,
    }}
    if image1 == image2 {
        fmt.Println("image1 and image2 are equal")
    }
}

在上面的程序中,image 結構體類型包含了一個字段 data,該字段是 map 類型。map 是不可比較的類型,因此 image1 和 image2 是不可比較的。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • golang中是沒有class的,但是有一個結構體struct,有點類似,他沒有像java,c++中繼承的概念,但...
    Link_Biao閱讀 1,329評論 0 1
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,758評論 18 399
  • Golang是一門很特殊的語言,雖然它出生比較晚,但是在很多地方卻和現在的編程語言有所不同。現在的編程語言要么是函...
    樂百川閱讀 3,455評論 0 0
  • 有時候項目開發會遇到一個結構體的Json轉換的時間格式問題。 即這種1993-01-01T20:08:23.000...
    不會寫代碼的程序猿閱讀 13,781評論 3 2
  • 近來因閑,復讀《紅樓夢》,月余掩卷。可謂歡喜嘆息自半。歡喜著跟著一群玲瓏剔透的人兒入了大觀園,嘆息人世無常,親生的...
    梅園遺珠閱讀 294評論 2 4