七、golang中介面、反射

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

一、介面定義

1、定義

interface類型可以定義一組方法,但是這些不需要實現,並且interface不能包含任何變數

package mainimport (   "fmt")type test interface{   print()}type Student struct{   name string   age int   score int}func (p *Student)print(){   fmt.Println("name",p.name)   fmt.Println("age",p.age)   fmt.Println("score",p.score)}func main(){   var t test              //建立介面對象   var stu Student=Student{   //執行個體化結構體      name:"stu1",      age:20,      score:100,   }   t=&stu     //把執行個體化傳給這個介面對象   t.print()     //介面對象來調用介面的方法}name stu1age 20score 100上面的test就是一種類型

 

多態:

一種食物的多種形態,都可以按照統一的介面進行操作

上面的t可以指向Stu,也可以指向其他類型,這個就是多態

定義:

   比如:

   type  example interface{

         method1(參數列表) 傳回值列表

   method2(參數列表) 傳回值列表

}

interface類型預設是一個指標

介面實現:

a、golang中的介面,不需要顯示的實現,只要一個變數,含有介面類型中的所有方法,那麼這個變數就實現這個介面

b、如果一個變數含有多個interface類型的方法,那麼這個變數就實現了多個介面

c、要實現變數中介面的所有方法,才是實現了這個介面

 

介面嵌套:

一個介面可以嵌套在另外的介面,如下所示

type ReadWrite interface{

         Read(b Buffer) bool

         Write(b Buffer)bool

}

type Lock interface{

         Lock()

         Unlock()

}

type File interface{

         ReadWrite

         Lock

         Close()

}

類型斷言

類型斷言,由於介面是一般類型,不知道具體類型,如果要轉成具體類型,可以採用以下方法進行轉換

 

var t int              var t int

var x interface{}    var x interface {}

x=t              x=t

y=x.(int)//轉成int  y ,ok=x.(int)  //轉成int,帶檢查

二叉排序樹

時間複雜度和二分尋找時間複雜度是一樣的

 

為什麼要使用介面?

介面是一個規範,不需要關注類等的實現。即,資料本來在mysql裡面然後突然變成pg裡面,只要介面不變,使用方就不需要更改

 

如果介面裡面沒有任何方法,那麼我們就叫這個介面為空白介面

 

package mainimport (   "fmt")type Carer interface{   GetName() string   Run()   DIDI()}func main(){   var car Carer   fmt.Println(car)  //<nil>}上面列印出這個介面的值為nil

下面具體介面的用法:

 

package main

import (
   "fmt"
)

type Carer interface{
   GetName() string   //這裡前面定義的方法,後面代表傳回值類型
   Run()
   DIDI()
}

type BWM struct{
   Name string
}

func (p *BWM)GetName() string{
   return p.Name
}

func (p *BWM)Run(){
   fmt.Printf("%s isRunning",p.Name)
}

func (p *BWM)DIDI(){
   fmt.Printf("%s isdidi",p.Name)
}

func main(){
   var car Carer
   fmt.Println(car)  //<nil>

   bwm:=BWM{
      Name:"bwm",
   }
   car=&bwm
   car.Run()
}

 

 

介面操作小結:

1、定義介面和方法,注意傳回值

2、定義類型

3、定義類型實現的介面的方法,注意這裡要實現介面所有的方法

4、聲明定義的類型,聲明介面變數的類型並且初始化,並把定義的類型賦值給介面變數的類型,注意指標

5、用定義的介面變數執行介面方法

鴨子類型

只要實現了介面相關的協議,那麼這個就是介面

 

如sort只需要實現下面的介面就可以

func Sort(data Interface) 這裡只需要傳入介面就可以了

這個介面實現下面的方法

type Interface interface{

         Len()int           長度

         Less(I,jint) bool     比較兩個數

         Swap(I,jint)        交換兩個數

}

注意下面的大小寫

 

package mainimport (   "fmt"   "math/rand"   "sort")type Student struct{   Name string   Id string   Age int}type StudentArray []Student  //定義這個是切片結構體func (p StudentArray) Len() int {   return len(p)}func (p StudentArray)Less(i,j int)bool{   return p[i].Name>p[j].Name      //從大到小}func (p StudentArray)Swap(i,j int){   p[i],p[j]=p[j],p[i]}func main() {   var stus StudentArray   for i := 0; i < 10; i++ {      stu := Student{         Name: fmt.Sprintf("stu%d", rand.Intn(100)),         Id:   fmt.Sprintf("110%d", rand.Int()),         Age:  rand.Intn(100),      }      stus = append(stus, stu)   }   for _, v := range stus {      fmt.Println(v)   }   //空行   fmt.Println("\n\n")   //由於這裡實現了sort的介面,所以這裡可以直接調用   sort.Sort(stus)            for _, v := range stus {      fmt.Println(v)   }}

反射

反射,可以在運行時動態擷取變數的相關資訊

import (“reflect”)

兩個函數

a)reflect.TypeOf,擷取變數的類型,返回reflect.Type類型

b)reflect.ValueOf 擷取變來那個的值,返回reflect.Value類型

c) reflect.Value.Kind 擷取變數的類別,返回一個變數

d) reflect.value.Interface()  轉換成interface類型

 

a和c的區別:

類型和類別的區別

類別範圍》類型

 

package mainimport(   "fmt"   "reflect")type Student struct{   Name string   Age int   Score float32}func test(b interface {}){   t:=reflect.TypeOf(b)   fmt.Println(t)   //main.Student  類型   v:=reflect.ValueOf(b)   k:=v.Kind()   fmt.Println(k)    //struct類別   iv:=v.Interface()   stu,ok:=iv.(Student)   if ok{      fmt.Printf("%v %T\n",stu,stu)//{stu01 18 92} main.Student   }}func main(){   var a Student=Student{      Name:"stu01",      Age:18,      Score:92,   }   test(a)}可以在動態運行時的時候的到b的很多資訊,這就是反射上面是三種轉換下main是擷取值package mainimport(   "fmt"   "reflect")type Student struct{   Name string   Age int   Score float32}func test(b interface {}){   t:=reflect.TypeOf(b)   fmt.Println(t)   //main.Student  類型   v:=reflect.ValueOf(b)   k:=v.Kind()   fmt.Println(k)    //struct類別   iv:=v.Interface()   stu,ok:=iv.(Student)   if ok{      fmt.Printf("%v %T\n",stu,stu)//{stu01 18 92} main.Student   }}func testInt(b interface{}){   val :=reflect.ValueOf(b)   c:=val.Int()           //擷取值   fmt.Printf("get value interface{} %d",c)//get value interface{} 1234}func main(){   var a Student=Student{      Name:"stu01",      Age:18,      Score:92,   }   test(a)   testInt(1234)}小結:1、反射擷取具體的了類型2、轉化為具體的值3、.Int()等擷取具體的值4、才能列印輸出值

  

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.