位元詩人 [Golang] 程式設計教學:使用結構 (Struct)

Golang結構
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

在先前的程式中,我們的變數都是儲存單一的值。如果想用變數表示較複雜的概念,像是在平面座標系中的某個點,先前的語法就不敷使用了。在 Go 語言,使用結構 (struct) 來表示複合的概念;此外,大部分的 Go 物件導向程式也會使用結構。本篇文章會介紹結構,但暫時不接觸物件導向的部分。

Go 使用 struct 做為結構的關鍵字,這是承襲 C 的慣例。實例如下:

package main

import (
    "fmt"
)

type Point struct {
    x float64
    y float64
}

func main() {
    p := Point{x: 3.0, y: 4.0}

    fmt.Println(p.x)
    fmt.Println(p.y)
}

我們通常會在宣告結構時一併定義新的型別,便於後續程式呼叫,使用 type 可以宣告新型別。在本例中,我們宣告 Point 型別,該型別有兩個屬性 (field),分別是 xy,兩者皆是 float64 型別;接著,我們宣告一個變數 p 及賦值;最後,我們呼叫 p 的屬性 xy

如果我們只需要使用結構,但不想創造新的型別,也可以使用匿名結構。實例如下:

package main

import (
    "fmt"
)

func main() {
    p := struct {
        x float64
        y float64
    }{x: 3.0, y: 4.0}

    fmt.Println(p.x)
    fmt.Println(p.y)
}

透過使用結構,我們可以比較有效率地處理數據。如下例:

package main

import (
    "fmt"
    "math"
)

type Point struct {
    x float64
    y float64
}

func main() {
    p := Point{x: 3.0, y: 4.0}
    q := Point{x: 0.0, y: 0.0}

    distance := math.Sqrt(math.Pow(p.x-q.x, 2) + math.Pow(p.y-q.y, 2))
    fmt.Println(distance)
}

結構的屬性,不一定要相同。見以下實例:

package main

import (
    "fmt"
)

type Gender int

const (
    Male Gender = iota
    Female
)

type Person struct {
    name   string
    gender Gender
    age    uint
}

func main() {
    me := Person{gender: Female, age: 30, name: "Michelle Chen"}

    fmt.Println(me.name)
    fmt.Println(me.age)

    if me.gender == Male {
        fmt.Println("Male")
    } else {
        fmt.Println("Female")
    }
}

在本程式中,我們先宣告新的型別 Gender,再定義相關的常數 MaleFemale;在這裡,我們使用 iota 自動產生常數。接著,宣告新的型別 Person,該型別有三個屬性,分別是 namegenderage,其中 gender 用到先前宣告的 Gender 型別。我們宣告新的變數 me並賦值,最後,將值印出;尤於 gender 內部是整數常數,無法印出,故自行轉為可識別的字串。

結構內也可以再加入另一個結構,如下例:

package main

import (
    "fmt"
    "math"
)

type Point struct {
    x float64
    y float64
}

type Circle struct {
    r float64
    p Point
}

func main() {
    c := Circle{r: 5.0, p: Point{x: 3.0, y: 4.0}}

    fmt.Println(c.p.x)
    fmt.Println(c.p.y)

    circumstance := 2 * math.Pi * c.r
    fmt.Println(circumstance)
}

在本例中,結構 c 有兩個屬性,分別是半徑 r 和坐標 p,其中 p 本身又是由另一個結構組成。

透過本例,各位讀者應該可以知道結構的基本使用方法。至於物件導向程式的部分,則待後續文章說明。在下一篇文章中,我們會介紹 Go 的內建容器 (collection):陣列 (array) 和切片 (slice)。

關於作者

身為資訊領域碩士,位元詩人 (ByteBard) 認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

位元詩人喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,位元詩人將所學寫成文章,放在這個網站上和大家分享。