# Go 方法
一般的函數定義叫做函數,定義在結構體上面的函數叫做該結構體的方法。
示例1:
```go
package main
import "fmt"
type rect struct {
width, height int
}
// 這個area方法有一個限定類型*rect,
// 表示這個函數是定義在rect結構體上的方法
func (r *rect) area() int {
return r.width * r.height
}
// 方法的定義限定類型可以為結構體類型
// 也可以是結構體指針類型
// 區別在于如果限定類型是結構體指針類型
// 那么在該方法內部可以修改結構體成員信息
func (r rect) perim() int {
return 2*r.width + 2*r.height
}
func main() {
r := rect{width: 10, height: 5}
// 調用方法
fmt.Println("area: ", r.area())
fmt.Println("perim:", r.perim())
// Go語言會自動識別方法調用的參數是結構體變量還是
// 結構體指針,如果你要修改結構體內部成員值,那么使用
// 結構體指針作為函數限定類型,也就是說參數若是結構體
//變量,僅僅會發生值拷貝。
rp := &r
fmt.Println("area: ", rp.area())
fmt.Println("perim:", rp.perim())
}
```
輸出結果為
```
area: 50
perim: 30
area: 50
perim: 30
```
示例2:
從某種意義上說,方法是函數的“語法糖”。當函數與某個特定的類型綁定,那么它就是一個方法。也證因為如此,我們可以將方法“還原”成函數。
instance.method(args)->(type).func(instance,args)
為了區別這兩種方式,官方文檔中將左邊的稱為`Method Value`,右邊則是`Method Expression`。Method Value是包裝后的狀態對象,總是與特定的對象實例關聯在一起(類似閉包,拐帶私奔),而Method Expression函數將Receiver作為第一個顯式參數,調用時需額外傳遞。
注意:對于Method Expression,T僅擁有T Receiver方法,*T擁有(T+*T)所有方法。
```go
package main
import (
"fmt"
)
func main() {
p := Person{2, "張三"}
p.test(1)
var f1 func(int) = p.test
f1(2)
Person.test(p, 3)
var f2 func(Person, int) = Person.test
f2(p, 4)
}
type Person struct {
Id int
Name string
}
func (this Person) test(x int) {
fmt.Println("Id:", this.Id, "Name", this.Name)
fmt.Println("x=", x)
}
```
輸出結果:
```
Id: 2 Name 張三
x= 1
Id: 2 Name 張三
x= 2
Id: 2 Name 張三
x= 3
Id: 2 Name 張三
x= 4
```
示例3:
使用匿名字段,實現模擬繼承。即可直接訪問匿名字段(匿名類型或匿名指針類型)的方法這種行為類似“繼承”。訪問匿名字段方法時,有隱藏規則,這樣我們可以實現override效果。
```go
package main
import (
"fmt"
)
func main() {
p := Student{Person{2, "張三"}, 25}
p.test()
}
type Person struct {
Id int
Name string
}
type Student struct {
Person
Score int
}
func (this Person) test() {
fmt.Println("person test")
}
func (this Student) test() {
fmt.Println("student test")
}
```
輸出結果為:
```
student test
```
- 版權
- 內容
- Go常量
- Go變量
- Go 數值
- Go 數組
- Go 字典
- Go 函數定義
- Go 方法
- Go 結構體
- Go 閉包函數
- Go 接口
- Go 字符串操作函數
- Go 字符串格式化
- Go 自定義排序
- Go Base64編碼
- Go Defer
- Go Exit.md
- Go for循環
- Go if..else if..else 條件判斷
- Go JSON支持
- Go Line Filters
- Go 狀態協程
- Go Panic
- Go range函數
- Go SHA1 散列
- Go String與Byte切片之間的轉換
- Go Switch語句
- Go URL解析
- Go 遍歷通道
- Go 并行功能
- Go 并行通道Channel
- Go 超時
- Go 錯誤處理
- Go 打點器
- Go 遞歸函數
- Go 讀取文件
- Go 工作池
- Go 關閉通道
- Go 函數多返回值
- Go 函數回調
- Go 函數命名返回值
- Go 互斥
- Go 環境變量
- Go 集合功能
- Go 計時器
- Go 進程觸發
- Go 進程執行
- Go hello world
- Go 可變長參數列表
- Go 命令行參數
- Go 命令行參數標記
- Go 排序
- Go 切片
- Go 請求處理頻率控制
- Go 時間
- Go 時間戳
- Go 時間格式化和解析
- Go 數字解析
- Go 隨機數
- Go 通道的同步功能
- Go 通道方向
- Go 通道緩沖
- Go 通道選擇Select
- Go 寫入文件
- Go 信號處理
- Go 原子計數器
- Go 正則表達式
- Go 指針