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中的成员,会被忽略冲突,编译不会报错;
//否则会存在二义性错误;

 

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