- Go 語言的面向?qū)ο缶幊谭绞脚c傳統(tǒng)的
C++
抬纸、Java
睡陪、Python
等語言不同
- Go 語言的標(biāo)準(zhǔn)庫大部分情況下提供的都是函數(shù)包,但也適當(dāng)?shù)靥峁┝税椒ǖ淖远x類型
幾個關(guān)鍵概念
- Go 語言不支持繼承
- Go 語言只支持聚合(也叫做組合)和嵌入,例子:
type ColoredPoint struct {
color.Color // 匿名字段(嵌入)
x, y int // 具名字段(聚合)
}
- 術(shù)語“類”(class)厌丑、“對象”(object)、以及“實(shí)例”(instance)在傳統(tǒng)的多層次繼承式面向?qū)ο缶幊讨幸约岸x的非常清晰渔呵,但在 Go 語言中我們完全避開使用它們
- 由于沒有繼承怒竿,因此也就沒有虛函數(shù),Go 語言對此的支持是采用類型安全的鴨子類型(duck type)
- 參數(shù)可以被聲明為一個具體的類型(例如扩氢,
int
耕驰、string
或者 *os.File
以及 MyType
),也可以是接口(interface
)录豺,既提供了具有滿足該接口的方法的值
- 繼承的一個優(yōu)點(diǎn)是朦肘,有些方法只需在基類中實(shí)現(xiàn)一次,即可在子類中方便地使用巩检,Go 語言為此提供了兩種解決方法:
- 一種方法是嵌入厚骗,如果嵌入了一個類型,方法只需在所嵌入的類型中實(shí)現(xiàn)一次兢哭,即可在所有包含該嵌入類型的類型中使用
- 為每一種類型提供獨(dú)立的方法领舰,但是只是簡單地將包裝(通常都只有一行)了功能性作用的代碼放進(jìn)了一個函數(shù),然后將所有類的方法都調(diào)用這個函數(shù)
- Go 語言面向?qū)ο缶幊讨械牧硪粋€與眾不同點(diǎn)是它的接口迟螺、值和方法都相互保持獨(dú)立
- 接口用于聲明方法簽名冲秽,結(jié)構(gòu)體用于聲明聚合或者嵌入的值,而方法用于聲明在自定義類型(通常為結(jié)構(gòu)體)上的操作
自定義類型
type typeName typeSpecification
-
typeName
可以是一個包或者函數(shù)內(nèi)唯一的任何合法的 Go 標(biāo)識符
-
typeSpecification
可以是任何內(nèi)置的類型(如 string
矩父、int
锉桑、切片
、映射
或者 通道
)窍株、一個接口民轴、一個結(jié)構(gòu)體或者一個函數(shù)簽名
- 下面是沒有方法的自定義類型例子:
type Count int
type StringMap map[string] string
type FloatChan chan float64
var i Count = 7
i++
fmt.Println(i)
sm := make(StringMap)
sm["key1"] = "value1"
sm["key2"] = "value2"
fmt.Println(sm)
fc := make(FloatChan, 1)
fc <- 2.29558714939
fmt.Println(<-fc)
- 像
Count
、StringMap
球订、FloatChan
這樣的類型后裸,他們是直接基于內(nèi)置類型創(chuàng)建的,硬扯可以拿來當(dāng)做內(nèi)置類型一樣使用
- 如果要將其傳遞給一個接受其底層類型的函數(shù)冒滩,就必須先將其轉(zhuǎn)換成底層類型(無需成本微驶,因?yàn)槭窃诰幾g時完成)
- 我們也可能需要進(jìn)行相反的操作,建一個內(nèi)置類型的值升級成一個自定義類型的值,以使用其自定義類型的方法因苹,例子:
type RuneForRuneFunc func(rune) rune
var removePunctuation RuneForRuneFunc
phrases := []string{"Day; dusk, and night.", "All day long"}
removePunctuation = func(char rune) rune {
if unicode.Is(unicode.Terminal_punctuation, char) {
return -1
}
return char
}
processPhrases(phrases, removePunctuation)
func processPhrases(phrases []string, function removePunctuation) {
for _, phrase := range phrases {
fmt.Println(strings.Map(function, phrase))
}
}
- 基于內(nèi)置類型或者函數(shù)簽名創(chuàng)建自定義的類型非常有用苟耻,但對我們來說遠(yuǎn)遠(yuǎn)不夠