📕
Go 語言程式設計入門
  • 最新消息
  • 中文版更新日誌
  • 譯者誌謝
  • 01-起步走
    • 01.01-檔案與資料夾
    • 01.02-終端機(Terminal)
    • 01.03-文字編輯器
    • 01.04-Go 的工具
  • 02-你的第一個程式
    • 02.01-如何讀 Go 程式
    • 02.02-問題
  • 03-型別
    • 03.01-數字
    • 03.02-字串
    • 03.03-問題
  • 04-變數
    • 04.01-如何命名變數
    • 04.02-Scope(變數的作用範圍)
    • 04.03-常數(Constant)
    • 04.04-定義多個變數
    • 04.05-範例程式
    • 04.06-問題
  • 05-控制結構
    • 05.01-For
    • 05.02-If
    • 05.03-switch
    • 05.04-問題
  • 06-Array、Slice 與 Map
    • 06.01-陣列(Array)
    • 06.02-Slice
    • 06.03-Map
    • 06.04-問題
  • 07-函式
    • 07.01-你的第二個函式
    • 07.02-回傳多個值
    • 07.03-參數個數可變的函式(Variadic Function)
    • 07.04-Closure
    • 07.05-遞迴(Recursive)
    • 07.06-Defer, Panic & Recover
    • 07.07-Panic & Recover
    • 07.08-問題
  • 08-指標
    • 08.01-「*」與「&」運算符號
    • 08.02-new
    • 08.03-問題
  • 09-Struct 與 Interface
    • 09.01-struct
    • 09.02-Method
    • 09.03-Interface
    • 09.04-問題
  • 10-Concurrency(平行處理)
    • 10.01-Goroutine
    • 10.02-Channel
    • 10.03-問題
  • 11-Packages
    • 11.01-建立 Package
    • 11.02-文件
    • 11.03-問題
  • 12-測試
  • 13-The Core Packages
    • 13.01-字串
    • 13.02-輸入與輸出
    • 13.03-檔案與資料夾
    • 13.04-錯誤訊息
    • 13.05-Container 與 Sort
    • 13.06-雜湊&加解密
    • 13.07-伺服器
    • 13.08-解析命令列參數
    • 13.09-Synchronization Primitives(同步處理原始物件)
  • 14-下一步
    • 14.01-閱讀大師作品
    • 14.02-動手實作
    • 14.03-團隊合作
  • 15. 附錄-額外資源
Powered by GitBook
On this page
Edit on GitHub
  1. 09-Struct 與 Interface

09.02-Method

雖然現在的程式碼比初版好了許多,不過我們還可以用一個所謂的 method 特殊型別來大幅改善程式碼:

func (c *Circle) area() float64 {
    return math.Pi * c.r*c.r
}

在 func 關鍵字與函式名稱之間,我們已經新增了一個 “receiver”,receiver 就像是一個參數,具有名稱與型別,但透過此方式建立函式可讓我們使用 . 運算符來呼叫函式:

fmt.Println(c.area())

這樣很易於閱讀,我們不再需要 & 運算符(Go 語言能自動知道要傳遞一個指標給此 method 的 circle),而且因為此函式只能用在 Circle,所以我們可以重新將函式只命名為 area。

現在替 rectangle 做同樣的設計:

type Rectangle struct {
    x1, y1, x2, y2 float64
}
func (r *Rectangle) area() float64 {
    l := distance(r.x1, r.y1, r.x1, r.y2)
    w := distance(r.x1, r.y1, r.x2, r.y1)
    return l * w
}

main 具有:

r := Rectangle{0, 0, 10, 10}
fmt.Println(r.area())

嵌入式型別

一個 struct 的欄位通常代表有一個關係,例如:一個 Circle 有一個 radius,假設我們有一個 person 這樣的 struct:

type Person struct {
    Name string
}
func (p *Person) Talk() {
    fmt.Println("Hi, my name is", p.Name)
}

而且我們想要建立一個新的 Android struct,我們可以這樣寫:

type Android struct {
    Person Person
    Model string
}

這是可以運作的,而我們會說這樣宣告的意思是:Android 「是」一個人,而不是說 Android「含有」(「擁有」)一個人。Go 語言透過嵌入式型別(embedded type)提供這類關係,也就是所謂的匿名欄位(anonymous field),嵌入式型別看起來類似這樣:

type Android struct {
    Person
    Model string
}

我們使用(Person)型別,而且不幫它取名字。當以這個方式定義時,就可以使用這個型別名稱來存取 Person struct:

a := new(Android)
a.Person.Talk()

不過我們也可以直接在 Android 上呼叫任何的 Person method:

a := new(Android)
a.Talk()

這是一個直觀的關係:人可以說話,而一個 android 是一個人,因此 android 可以說話。

Previous09.01-structNext09.03-Interface

Last updated 2 years ago