方法method
- go中沒有class,但依舊有method
- 通過顯示說明receiver來實現(xiàn)與某個類型的組合
- 只能為同一個包中的類型定義方法
- receiver可以是類型的值或者指針
- 不存在方法重載
- 可以使用值或指針來調(diào)用方法笆制,編譯器會自動完成轉(zhuǎn)換
- 從某種意義上來熟,方法是函數(shù)的語法糖,因為receiver其實就是方法所接收的第一個參數(shù)(Method Value vs. Method Expression)
- 如果外部結(jié)構(gòu)和嵌入結(jié)構(gòu)存在同名方法,則優(yōu)先調(diào)用外部結(jié)構(gòu)的方法
- 類型別名不會擁有底層類型所附帶的方法
- 方法可以調(diào)用結(jié)構(gòu)中的非公開字段
package main
import "fmt"
type A struct {
Name string
}
type B struct {
Name string
}
func main() {
a := A{}
a.Print()
b := B{}
b.Print()
}
// 方法存在接收者缆镣,對應(yīng)的是一個結(jié)構(gòu)
// 這里對應(yīng)的是結(jié)構(gòu)A
func (a A)Print(){
fmt.Println("A") // A
}
// 對應(yīng)結(jié)構(gòu)B
func (a B)Print(){
fmt.Println("B") // B
}
指針傳遞
package main
import "fmt"
type A struct {
Name string
}
type B struct {
Name string
}
func main() {
a := A{}
a.Print()
fmt.Println(a.Name) // AA
b := B{}
b.Print()
fmt.Println(b.Name) // 空字符
}
// 指針傳遞可以修改
func (a *A)Print(){
a.Name = "AA"
fmt.Println("A") // A
}
// 非指針傳遞無法修改
func (b B)Print(){
b.Name = "BB"
fmt.Println("B") // B
}
類型別名,創(chuàng)建自己命名的類型试浙,同樣擁有方法
package main
import "fmt"
type Myint int
func main() {
// 這里聲明需要var
var a Myint
a.Print()
}
func (a Myint)Print(){
fmt.Println("Myint") // Myint
}
Method Value vs. Method Expression
package main
import "fmt"
type Myint int
func main() {
var a Myint
// Method Value
a.Print() // Myint
// Method Expression
(*Myint).Print(&a) // Myint
}
func (a Myint)Print(){
fmt.Println("Myint") // Myint
}
首字母小寫董瞻,能否訪問 class 中的方法是可以訪問私有字段的
package main
import "fmt"
type A struct {
name string
}
func main() {
a := A{}
a.Print()
fmt.Println(a.name) // james
}
func (a *A)Print(){
a.name = "james"
fmt.Println("A")
}
底層類型為int的類型,擁有方法可以將接收的int型從0轉(zhuǎn)變?yōu)?00
package main
import "fmt"
type Myint int
func main() {
var a Myint
a.Increase(100)
fmt.Println(a)
}
func (a *Myint)Increase(num int){
// 類型需要轉(zhuǎn)換才能運算
*a += Myint(num)
}
接口interface
- 接口是一個或多個方法簽名的集合
- 只要某個類型擁有該接口的所有方法簽名田巴,即算實現(xiàn)該接口钠糊,無需顯示聲明實現(xiàn)了哪個接口,這稱為Structural Typing
- 接口只有方法聲明壹哺,沒有實現(xiàn)抄伍,沒有數(shù)據(jù)字段
- 接口可以匿名嵌入其他接口,或嵌入到結(jié)構(gòu)中
- 將對象賦值給接口時管宵,會發(fā)生拷貝截珍,而接口內(nèi)部存儲的是指向這個復(fù)制品的指針,既無法修改復(fù)制品的狀態(tài)箩朴,也無法獲取指針
- 只有當(dāng)接口存儲的類型和對象都為nil時岗喉,接口才等于nil
- 調(diào)用接口不會做receiver的自動轉(zhuǎn)換
- 接口同樣支持匿名字段方法
- 接口也可以實現(xiàn)類似oop中的多態(tài)
- 空接口可以作為任何類型數(shù)據(jù)的容器
`