這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
一、介面定義
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、才能列印輸出值