再golang中,咱們要充分理解interface和struct這兩種數據類型。爲此,咱們須要優先理解type的做用。golang
type是golang語言中定義數據類型的惟一關鍵字。對於type中的匿名成員和指針成員,這裏先不講,重點講解interface和struct這兩種特殊的數據類型。數據結構
interface和struct也是數據類型,特殊在於interface做爲萬能的接口類型,而struct做爲經常使用的自定義數據類型的關鍵字。說到這裏相比你們已經明白interface的側重點在於接口的定義(方法),而struct側重點在於數據結構的定義。使用struct定義了數據結構,能夠直接使用func方法定義數據結構中使用的方法。可是爲了解耦,爲了擴展,通常在真正設置功能性函數時,除了內置的數據類型外,都推薦使用接口的方法來傳遞相關方法。函數
既然推薦使用接口的方法來做爲參數,那麼具體結構中的數據成員又如何訪問呢?golang提供了很是方便的類型查詢和類型轉換方法。名稱.(type)用於類型查詢,名稱.(具體類型)用於類型轉換。所以,使用接口做爲函數參數是頗有價值的。測試
另外,咱們還須要明白對象和對象指針在golang中的微妙處理,golang能夠自動將對數據類型定義的方法抓轉換成對數據類型指針定義的方法。但不能自動的將對數據類型指針的方法轉換爲對數據類型定義的方法。spa
如下是咱們的測試程序,註釋已經註明了相關說明。指針
package main import "fmt" //定義一個接口 type Stryc interface { Int() int } //定義一個自定義數據類型 type myCls struct { value int } //使用數據類型指針綁定方法(在調用方法時,數據類型在golang中會默認轉換爲數據類型指針進行使用) func(a * myCls) Int() int{ return a.value } //定義一個函數,參數爲一個自定義的數據類型 func printTheValueByStruct(arg myCls){ fmt.Printf("the value is %d \n",arg.Int()) } //定義一個函數,參數爲一個接口 func printTheValue(arg Stryc) int{ fmt.Printf("the value is %d \n",arg.Int()/*使用接口調用接口的方法*/) return arg.Int() } //定義一個函數,參數爲動態個數的接口類型參數 func printAnyValue(args ...interface{}){ //使用for range方法獲取每個接口 for _,arg := range args{ //使用.(type)方法查詢接口的數據類型 switch arg.(type) { case int: fmt.Println("the type is int") case string: fmt.Println("the type is string") case myCls:/*是自定義數據類型*/ //使用.(數據類型)進行強轉 var b myCls = arg.(myCls) fmt.Println("the type is myCls, the function value is ", b.Int()/*d調用數據類型的方法,golang會轉換爲數據指針類型調用*/,"the struct value is ", b.value/*調用數據結構的數據*/) case Stryc:/*是定義的接口數據類型*/ fmt.Println("the type is Stryc interface, the function value is ", arg.(Stryc).Int()/*將接口強轉到指定接口,並調用方法*/) } } } func main(){ var V1 *myCls = new(myCls) //建立一個對象指針 V1.value = 1111111 //給對象賦值 var V2 myCls = myCls{222222222} //建立一個對象,給對象賦值 var a interface {}=myCls{33333} //建立一個對象,將對象賦值後傳給一個萬能類型接口 var a1 interface{}=&myCls{444444}//建立一個對象,將對象指針傳給一個萬能類型接口 fmt.Println("hello world!") printTheValue(V1) //V1會轉換爲Stryc接口被調用其中的方法 printTheValue(a1.(Stryc)) //萬能接口a1中放置的對象指針被強制轉爲Stryc接口調用 printTheValueByStruct(*V1) //強制將V1的對象使用*顯示傳入函數,由於參數是對象 printTheValueByStruct(a.(myCls))//強制將萬能接口a中放置的對象轉換爲對象傳入函數,由於參數是對象 printTheValue(&V2) //將對象的指針傳入函數,golang將其轉換爲Stryc接口 printAnyValue(V1/*傳入一個指針,會同Stryc接口數據類型匹配*/, V2/*傳入一個對象,會同myCls數據類型匹配*/, *V1/*將指針顯示爲對象傳入,會同myCls數據類型匹配*/, &V2/*將對象的指針傳入,會同Stryc接口數據類型匹配*/) }
如下是執行結果code
hello world! the value is 1111111 the value is 444444 the value is 1111111 the value is 33333 the value is 222222222 the type is Stryc interface, the function value is 1111111 the type is myCls, the function value is 222222222 the struct value is 222222222 the type is myCls, the function value is 1111111 the struct value is 1111111 the type is Stryc interface, the function value is 222222222