GO在文檔中強(qiáng)調(diào)了根本沒有繼承這一概念
1.屏蔽現(xiàn)象
一個簡單的demo
package main
import (
"fmt"
)
var name = 11
func main(){
var name =10
{
var name = 9
fmt.Println(name)
}
fmt.Println(name)
}
結(jié)果很明顯鞭盟,輸出9闸翅,10
根據(jù)對作用域的理解月褥,程序?qū)嶓w的訪問權(quán)限由代碼塊控制等浊,變量也屬于程序?qū)嶓w, 嵌套的代碼塊導(dǎo)致變量出現(xiàn)被屏蔽的現(xiàn)象欲诺。這稱為變量的屏蔽現(xiàn)象
那函數(shù)呢抄谐?
package main
import (
"fmt"
)
type AnimalCategory struct {
kingdom string // 界。
phylum string // 門扰法。
class string // 綱蛹含。
order string // 目。
family string // 科塞颁。
genus string // 屬浦箱。
species string // 種。
}
func (ac AnimalCategory) String() string {
return fmt.Sprintf("hi%s%s%s%s%s%s%s",
ac.kingdom, ac.phylum, ac.class, ac.order,
ac.family, ac.genus, ac.species)
}
type Animal struct {
scientificName string // 學(xué)名祠锣。
AnimalCategory // 動物基本分類酷窥。這里嵌入其他結(jié)構(gòu)體
}
func (a Animal) String() string {
return fmt.Sprintf("%s (category: %s)",
a.scientificName, a.AnimalCategory)
}
func main(){
category := AnimalCategory{species: "cat"}
fmt.Printf("The animal category: %s\n", category)
animal := Animal{
scientificName: "American Shorthair",
AnimalCategory: category,
}
fmt.Printf("The animal: %s\n", animal)
}
我們發(fā)現(xiàn)在執(zhí)行 main函數(shù)中的打印函數(shù)時,雖執(zhí)行了Animal結(jié)構(gòu)體的String方法伴网,但是Animal中的String方法執(zhí)行a.AnimalCategory的字符串時蓬推,并沒有執(zhí)行
AnimalCategory結(jié)構(gòu)體定義的string方法,也就是說出現(xiàn)了同名函數(shù)的遮蔽現(xiàn)象澡腾。(Animal 內(nèi)嵌結(jié)構(gòu)體 AnimalCategory )
也就是說沸伏,雖然AnimalCategory利用嵌入字段糕珊,但是同名的方法還是會被覆蓋(內(nèi)嵌結(jié)構(gòu)體的同名方法不會被執(zhí)行)。
通過這個例子也就明白了Go中并沒有繼承的概念毅糟,Go語言利用了嵌入字段的特性红选,使得“子類”能夠坐享其成的使用“父類”(嵌入結(jié)構(gòu)體)的一切,即使某些方法不合心意留特,還可以利用屏蔽特性進(jìn)行“方法的重寫”去調(diào)整優(yōu)化
2.空結(jié)構(gòu)體
空結(jié)構(gòu)體不占用空間
package main
import (
"unsafe"
)
func main(){
var a = struct{}{}
var b = 1
fmt.Printf("%d,%d",unsafe.Sizeof(a),unsafe.Sizeof(b))
}
既然不占用內(nèi)存纠脾,那么我們就可以把他當(dāng)作是js的undefined的占位符(這里描述不準(zhǔn)確,undefined為一個變量蜕青,大致類比一下)來使用苟蹈,比如利用map和空結(jié)構(gòu)體來實(shí)現(xiàn)set
package main
import (
"fmt"
)
type Set map[string]struct{}
func (set Set) Has(s string) bool{
_,ok := set[s]
return ok
}
func (set Set) Add(s string) {
if ok := set.Has(s);!ok{
set[s] = struct{}{}
}
}
func (set Set) Del(s string){
delete(set,s)
}
func main(){
set := Set{}
fmt.Println(set.Has("a"))
set.Add("a")
fmt.Println(set.Has("a"))
set.Del("a")
fmt.Println(set.Has("a"))
}
實(shí)現(xiàn)不發(fā)送數(shù)據(jù)的通道,僅通知子協(xié)程執(zhí)行任務(wù)
func worker(ch chan struct{}) {
<-ch //協(xié)程阻塞右核,有struct時執(zhí)行任務(wù)
// TODO
fmt.Println("do something")
close(ch)
}
func main() {
ch := make(chan struct{})
go worker(ch)
ch <- struct{}{}
}
實(shí)現(xiàn)僅包含方法的結(jié)構(gòu)體 這里不再做贅述