《Go语言编程》学习总结3

参考书:Go语言编程

第三章  面向对象编程

1 Go语言中,你可以给任意类型(包括内置类型,但不包含指针类型)添加相应的方法,如下

        

type Integer int

func (a Integer) Less(b Integer) bool{   // 给Integer类型定义成员函数
   return a < b
}

func main(){
   var a Integer = 1
   if a.Less(2){
      fmt.Println(a," less 2")
   }
}

2 Go语言中没有隐藏的this指针,即方法施加的对象为显示传递,也不需要非得是指针,也不用非得叫this

3 数组作为参数传递为值传递,即函数内修改不会影响原数组,数组切片作为参数传递为引用传递,即函数内修改会影响原数组

4 如果需要修改对象,才必须使用指针,如下

type Integer int

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

func (a Integer) Add2(b Integer){
   a += b
}
func main(){
   var a1 Integer = 1
   a1.Add(2)
   fmt.Println("a = ",a1)    // 输出 a = 3,因为Add()传入的是指针
   a1.Add2(2)
   fmt.Println("a = ",a1)    // 输出 a = 3,因为Add2()传入的是值,所以函数修改不影响对象

}

5 Go语言的类型哪些属于值传递

  • 基础类型(如byte,int,bool,float32,float64和string等)和复合类型(如数组,结构体和指针等)属于值传递
  • 数组切片,map和channel,接口这4种类型一般属于引用类型

注:

1)数组切片本质是指向数组的一个区间,内部是指向数组的指针

2)map本质也是一个字典指针

3)channel和map类型,本质上也是一个指针

4)接口具备引用语义,是因为内部维持了两个指针,示意为:

            type interface struct  {

                    data  *void

                    itab   *Itab

            }

6 结构体,如下         

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

    func (r *Rect) Area() float64{
       return r.width * r.height
    }
   
   rect1 := new(Rect)     // 第一种初始化方式
   rect2 := &Rect{}       // 第二种初始化方式
   rect3 := &Rect{0,0,100,200}   // 第三种初始化方式
   rect4 := &Rect{width:100,height:100}    // 第四种初始化方式

7 匿名组合,用组合的方式来实现继承       

type Base struct {
   Name string
}

func (base *Base) Foo(){  }
func (base *Base) Bar(){  }

type Foo struct {
   Base
}

func (foo *Foo) Bar(){
   foo.Base.Bar()
}

8 Go语言中没有关键字private,public和protected,可访问性是包一级而不是类一级。

9 Go语言采用非侵入式接口

    type File struct {

            // toDo. . . 

      }

      func  (f *File) Read(buf []byte) (n int , err error)

      func  (f *File) Write(buf []byte) (n int , err error)

      func  (f *File) Seek(off int64 , whence int)  (pos int64 , err error)

      func  (f *File) Close( )   error

定义了一个File类,并实现有Read( ) , Write( ) , Seek( ) , Close( )等方法。设想我们有如下接口

      type IFile  interface {

               Read(buf []byte) (n int , err error)

               Write(buf []byte) (n int , err error)

               Seek(off int64 , whence int)  (pos int64 , err error)

               Close( )   error

      }

      type IReader  interface {

                Read(buf []byte) (n int , err error)

      }

      type IWriter  interface {

                Write(buf []byte) (n int , err error)

      }

      type ICloser  interface {

                Close( )   error      

      }

     var file1 IFile  = new(File)

     var file2 IReader = new(File)

     var file3 IWriter = new(File)

     var file4 ICloser = new(File)

10 将对象实例赋值给接口

type Integer int

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

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

type LessAdder interface {
   Add(b Integer)
   Less(b Integer) bool

}

type LessAdder2 interface {
   Less(b Integer) bool

}

   var a Integer = 1
   var b LessAdder = a     // error,因为LessAdder接口包含Add(),而类型a的Add()函数要改变对象值,需要地址赋值
   var c LessAdder = &a    // ok
   var d LessAdder2 = a    // ok,因为LessAdder接口没包含Add(),不要求地址赋值
   var e LessAdder2 = &a   // ok
 
 

11 接口给接口赋值,如果两个接口同样的方法列表可以相互赋值,如果一个接口的方法列表是另一个接口的方法列表的子集。接口可以赋值给子集的那个,不能反了。

      type File struct {

            // toDo. . . 

      }

      func  (f *File) Read(buf []byte) (n int , err error)

      func  (f *File) Write(buf []byte) (n int , err error)

      func  (f *File) Seek(off int64 , whence int)  (pos int64 , err error)

      func  (f *File) Close( )   error

      type A interface {

              Read(buf []byte) (n int , err error)

              Write(buf []byte) (n int , err error)

      }

      type B interface {

              Read(buf []byte) (n int , err error)

      }

      var file1 A = new(File)

      var file2 B = file1     // 接口A可以给接口B赋值,接口B是接口A的子集

12 接口查询,如下

            if file5 , ok := file1.(IReder) ; ok {   // 检查file1接口指向的对象实例是否实现了IReader接口

                     // toDo

            }

13 类型查询,采用 .(type) ,如下    

            var  i int = 12

            fmt.Println("i的类型为 ", i.(type))       // i的类型为int

14 Any类型:任何对象实例都满足空接口interface{ },如下

        var  v1  interface{ }  =  1 

        var  v2  interface{ }  =  "abc"

        var  v3  interface{ }  =  &v2 

        var  v4  interface{ }  =  struct{ X int }{1}





猜你喜欢

转载自blog.csdn.net/haima95/article/details/80840935
今日推荐