iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 16
1

默默超過鐵人賽的二分之一,雖然我自己也覺得這次參賽的文章養分有點不足,但至少我依然沒有放棄!

昨天的範例中忽然想起我漏掉了一個golang當中很重要的元素,也算是一種常見的資料型態--「Struct」,繁體中文的翻譯一樣付之闕如,中國翻譯為「結構體」或「結構」。我們可以在昨天的文章中發現他的身影:

type ContactDetails struct {
	Email   string
	Subject string
	Message string
}

以及更早以前的文章

type Todo struct {
	Title string
	Done  bool
}

type TodoPageData struct {
	PageTitle string
	Todos     []Todo
}

透過觀察上面這些範例,我們也可以知道結構體是一種資料結構,裡面由若干的欄位名稱、資料型態所組合而成,通常用來將商業邏輯相關的欄位組合成物件,方便操作。可以透過節點對各個欄位進行取值或給值。如果類別都相同,其實可以只寫一次,比方說上面的ContactDetails可以改寫為:

type ContactDetails struct {
	Email, Subject, Message string
}

跟原本的結構是一樣的效果。

結構體嵌入與匿名成員

結構體可以作為另一個結構體的成員之一,請看下面的例子:

//點
type Point struct {
    X, Y int
}
//圓
type Circle struct {
    Center Point
    Radius int
}
//車輪
type Wheel struct {
    Circle Circle
    Spokes int
}

這樣做的好處是相當好維護,彼此之間的關係也相當清晰。但是有一個缺點:

var w Wheel
w.Circle.Center.X = 8
w.Circle.Center.Y = 8
w.Circle.Radius = 5
w.Spokes = 20

那就是取值時變得相當繁瑣,雖然可以依此瞭解階層關係,但如果希望讓他變得更簡便,我們這個時候可以讓成員的結構體匿名,例如圓與車輪改寫如下:

type Circle struct {
    Point
    Radius int
}

type Wheel struct {
    Circle
    Spokes int
}

觀察一下兩者的差異,最主要就是作為成員的結構體不再有自己的名稱(例如之前的Center Point),只宣告結構體名稱,取值時可以變得更為簡便:

var w Wheel
w.X = 8            // 等同於 w.Circle.Point.X = 8
w.Y = 8            // 等同於 w.Circle.Point.Y = 8
w.Radius = 5       // 等同於 w.Circle.Radius = 5
w.Spokes = 20

可惜的是,給值不能用這樣的方法,可以參考下面:

w = Wheel{
    Circle: Circle{
        Point:  Point{X: 8, Y: 8},
        Radius: 5,
    },
    Spokes: 20, //特別注意,最後一個成員結尾的逗點是必要的
}
//簡寫為一行
w = Wheel{Circle{Point{8, 8}, 5}, 20}

輸出

在開發的階段,我們可能會需要印出結構體的所有欄位以及類別,我們介紹一下有關列印結構體的方法:

type T struct {
    a int
    b float64
    c string
}
t := &T{ 360, 9.2, "I'm a string." }

我們宣告一個結構,然後根據順序給值,宣告一個變數t。要印出t的內容物,我們可以使用下列這些方法:

fmt.Printf("%v\n", t)
fmt.Printf("%+v\n", t)
fmt.Printf("%#v\n", t)
  • %v:單純把內容都印出來,會得到&{7 -2.35 I'm a string.}
  • %+v:除了值以外,還有欄位名稱,得到&{a:7 b:-2.35 c:I'm a string.}
  • %#v:可以得到最多資訊,連結構體的名稱、所在的函數都會一起印出,得到&main.T{a:7, b:-2.35, c:"I'm a string."}

Reference


上一篇
Post 表單 2
下一篇
Interface 接口
系列文
啥物碗Golang? 30天就Go30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Alfred
iT邦新手 5 級 ‧ 2018-10-23 08:52:49

希望能講解interface的概念以及使用時機

Bater iT邦新手 4 級 ‧ 2018-10-23 21:28:31 檢舉

好,我今天來講interface

0
eric19740521
iT邦新手 1 級 ‧ 2020-08-01 16:45:10
w = Wheel{
        Circle{
            Point{8, 8},
            5},
        20,
        }

可以改成這樣
沒有,號 後面接}

w = Wheel{
        Circle{
            Point{8, 8},
            5},
        20}

我要留言

立即登入留言