go 類型系統

Go雖然是面向對象編程,但Go沒有函數的繼承語法,而是支持給任何類型(不包括指針類型)增加新方法的語法,只需要實現該接口要求的所有方法即可。

 

直接看以下幾個代碼例子

//例:給內置類型 int 添加Less方法

type Integer int

func (a Integer) Less(b Integer) bool {
    return a < b
}

func (a *Integer) Add(b Integer) {
    *a += b
}

func main(){
    var a Integer = 1

    if a.Less(21) {
        fmt.Println(a, "Less 21")
    }

    a.Add(2); // a=3
}
//自定義結構體
//順帶複習下結構體的初始化

type Rect struct{
    x,y float64
    width,height float64
}

func (r *Rect) Area() float64{
    return r.width * r.height
}

func main(){
    r1 := new(Rect)
    r2 := &Rect{}
    r3 := &Rect{0,0,1,2}
    r4 := Rect{ width:1.1, height:2.3 }
    r5 := Rect{ x:1.0, y:2.0, width:1.1, height:2.3 }
    
    r1.Area()
    r2.Area()
    r3.Area()
    r4.Area()
    r5.Area()
}

雖然Go語言沒有繼承,但有類似於繼承的做法,稱爲匿名組合

看代碼:

// 代碼演示 類似繼承 的 匿名組合 語法

type Base struct {
    Name string
}
func (base *Base) Foo(){
}
func (base *Base) Bar(){
}

type Foo struct{
    Base    // 組合
    Age int
    Addr string
}

func (foo *Foo) Bar(){
    foo.Base.Bar()    //調用組合結構中的接口
}

func main(){
    Foo f
    f.Bar()
    f.Base.Bar()
    //f.Bar() 和 f.Base.Bar() 調用效果完全一致
}
//本例子可以直觀演示 匿名組合 的使用技巧

type Job struct{
    Command string
    *log.Logger    //相當於'繼承'了log.Logger,可以直接使用log.Logger中的方法
}

func (job *Job) Start(){
    job.Log("starting now ...")
    // todo
    job.Log("started")
}

//對於Job結構的使用者來說,根本不用知道log.Logger類型的存在
//匿名組合中出現同名變量或同名組合者的情況

//1.同名變量
type X struct{
    Name string
}
type Y struct{
    X            // X.Name被隱藏,被外層的Name覆蓋
    Name string
}


//2.同名組合者
type Logger struct{
    Level int
}
type Y struct{
    *Logger
    Name string
    *log.Logger
}// 存在名稱都爲Logger的組合者
//如果沒有使用Logger中的成員,會被忽略衝突,編譯不會報錯;
//否則會存在二義性錯誤;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章