Go | 理解函式與方法的差異
💬 簡介
在上一篇中提到的「結構方法與接收器」,是否產生了疑問,到底什麼時候稱為『函式』什麼時候稱為『方法』。本文將深入探討這兩者的區別,並解釋它們在 Go 語言中的不同作用。
在 Go 語言中,函式(Function)與方法(Method)是兩個非常重要的概念。雖然它們在很多方面看起來相似,但其實在語法和用途上有所不同。
圖片來源:Gophers
🧐 什麼是函式?
在 Go 中,函式(Function) 是一段封裝了特定邏輯的程式碼,可以接受參數並返回結果。函式並不會綁定到特定的資料型別上,它是獨立的,並且可以在程式中任何地方被呼叫。
- 範例:
1
2
3
4
5
6
7
8
9
10
11
12package main
import "fmt"
// 定義一個函式
func greet(name string) {
fmt.Println("Hello,", name)
}
func main() {
greet("Alice") // 呼叫函式,輸出: Hello, Alice
}📝 在這個範例中,
greet
是一個普通的函式,它接受一個name
參數並打印消息。它並不依賴於任何特定的型別,也不操作任何資料結構。
🧐 什麼是方法?
方法(Method) 是一個特殊類型的函式,它是綁定到某個資料型別上的。方法會有一個叫做 接收器(Receiver) 的特殊參數,這個接收器是與特定型別的實例相關聯的。方法的最大特徵是,它可以操作這個資料型別的內部資料,從而能夠實現更具封裝性和行為定義的功能。
在 Go 中,方法是通過 接收器 來綁定到某個型別的。接收器的類型可以是值類型或指標類型,這會影響方法對結構資料的操作方式。
- 範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21package main
import "fmt"
// 定義一個結構
type Person struct {
Name string
}
// 定義一個方法,綁定到 Person 結構
func (p *Person) greet() {
fmt.Println("Hello,", p.Name)
}
func main() {
// 創建 Person 結構的實例
p := &Person{Name: "Bob"}
// 呼叫方法
p.greet() // 輸出: Hello, Bob
}📝 在這個範例中,我們定義了
greet
方法,並且綁定到Person
結構。這個方法可以訪問Person
的Name
欄位,並打印對應的訊息。方法的接收器(p *Person)
表示 greet 是一個綁定到Person
類型的指標方法,這樣方法可以直接修改Person
實例中的資料。
🔑 函式與方法的區別
雖然函式與方法在結構上非常相似,但在 Go 語言中,它們有幾個關鍵區別:
- 是否綁定到資料型別:
- 函式:不綁定到任何特定型別,獨立於型別存在。函式通常作為一段通用邏輯,接受參數並返回結果。
- 方法:綁定到特定資料型別(例如結構)。方法具有接收器,它是與特定型別的實例相關聯,並且能夠操作這個型別的內部資料。
- 接收器(Receiver):
- 函式:函式沒有接收器,它只接受傳入的參數。
- 方法:方法必須有接收器,它是方法所綁定的資料型別的實例。接收器可以是值型別或指標型別,這會決定方法對資料的操作方式。
- 資料操作:
- 函式:函式不能直接訪問綁定型別的欄位,它僅能操作函式傳遞的參數。
- 方法:方法能夠操作綁定型別的內部欄位,這使得它們可以直接改變型別的狀態。
🎯 總結
- 函式:獨立於資料型別,接受參數並返回結果,無法直接操作資料型別的欄位。
- 方法:綁定到資料型別,具有接收器,能夠操作該型別的欄位。
函式與方法其實不必太過於在意名稱區別,從實際使用來看,它們的功能和用途是相似的。大家常常聽到“方法”是因為它是綁定在型別上的函式,這樣的命名更能清楚表達它的作用,尤其在物件導向的設計中,將行為與資料綁定是很常見的模式。
最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。
註:以上參考了
Go