package main import ( "fmt" "reflect" "strconv" ) func main() { //interface類型 //interface類型定義了一組方法,如果某個對象實現了某個接口的"所有方法",則此對象就實現了此接口 //interface可以被任意的對象實現,一個對象可以實現任意多個interface //任意的類型都實現了空interface(我們這樣定義:interface{}),也就是包含0個method的interface。 //interface的值 /* mike := student{Human{"mike", 25}, "110"} paul := student{Human{"paul", 26}, "120"} lucy := employee{Human{"lucy", 18}, "001"} lily := employee{Human{"lily", 20}, "002"} //定義common類型的接口變量co var co common //co能夠存儲mike co = mike co.sayHi() co.sing() //co能夠存儲paul co = paul co.sayHi() co.sing() //co能夠存儲lucy co = lucy co.sayHi() co.sing() //co能夠存儲lily co = lily co.sayHi() co.sing() */ //空interface //空interface(interface{})不包含任何的method,正因為如此,所有的類型都實現了空interface。 //空interface在我們需要存儲任意類型的數值的時候相當有用,因為它可以存儲任意類型的數值。 /* var nullInterface interface{} var i int = 5 var str string str = "Hello world" Jim := student{Human{"Jim", 27}, "101"} nullInterface = i nullInterface = str nullInterface = Jim //一個函數把interface{}作為參數,那么他可以接受任意類型的值作為參數, //如果一個函數返回interface{},那么也就可以返回任意類型的值。 userInterfaceParam(nullInterface) fmt.Println("...") */ //interface函數參數 //任何實現了String方法的類型都能作為參數被fmt.Println調用 //實現了error接口的對象(即實現了Error() string的對象), //使用fmt輸出時,會調用Error()方法,因此不必再定義String()方法了 //interface變量存儲的類型 //知道interface的變量里面可以存儲任意類型的數值(該類型實現了interface)。 //怎么反向知道這個變量里面實際保存了的是哪個類型的對象 //Comma-ok斷言 //Go語言里面有一個語法,可以直接判斷是否是該類型的變量: value, ok = element.(T), //這里value就是變量的值,ok是一個bool類型,element是interface變量,T是斷言的類型。 //如果element里面確實存儲了T類型的數值,那么ok返回true,否則返回false。 //示例 type Element interface{} type List []Element list := make(List, 3) list[0] = 1 list[1] = "HelloWorld" list[2] = Human{"yang", 27} for index, element := range list { switch value := element.(type) { case int: fmt.Printf("list[%d] ,value is %d\n", index, value) case string: fmt.Printf("list[%d] ,value is %s\n", index, value) case Human: fmt.Printf("list[%d] ,value is %s\n ", index, value) default: fmt.Printf("list[%d] ,value is \n", index) } } //嵌入interface //如果一個interface1作為interface2的一個嵌入字段,那么interface2隱式的包含了interface1里面的method。 //反射 //1:反射成reflect對象-->2:對reflect對象進行操作,比如獲取它的值,或修改它的值 //1:反射成reflect對象 //t := reflect.TypeOf(i) //得到類型的元數據,通過t我們能獲取類型定義里面的所有元素 //v := reflect.ValueOf(i) //得到實際的值,通過v我們獲取存儲在里面的值,還可以去改變值 //2:對reflect對象進行操作,引入reflect包 //tag := t.Elem().Field(0).Tag //獲取定義在struct里面的標簽 //name := v.Elem().Field(0).String() //獲取存儲在第一個字段里面的值 //示例 //獲取值和類型 var x float64 = 3.4 v := reflect.ValueOf(x) fmt.Println("type:", v.Type()) fmt.Println("kind is float64:", v.Kind() == reflect.Float64) fmt.Println("value:", v.Float()) //修改值 要使用引用 var f float32 = 2.9 ff := reflect.ValueOf(&f) ff.Elem().SetFloat(3.8) fmt.Println(f) //這們會出錯 //ff := reflect.ValueOf(f) //ff.SetFloat(3.8) } type Human struct { name string age int } type student struct { Human schoolNumber string } type employee struct { Human employeeNumber string } func (h Human) sayHi() { fmt.Println("Hi!") } func (h Human) sing() { fmt.Println("la la la ~~") } func (s student) readBook() { fmt.Println(" reading book") } func (e employee) work() { fmt.Println("I'm working") } //Human、student、employee都實現了這個接口 type common interface { sayHi() sing() } //student實現了這個接口 type stuInterface interface { sayHi() sing() readBook() } //employee實現了這個接口 type empInterface interface { sayHi() sing() work() } //接收和返回interface類型,如果interface{}為空,那么它可以接收和返回任意類型的參數和值 func userInterfaceParam(i interface{}) interface{} { return i } func (h Human) String() string { return "(name: " + h.name + " - age: " + strconv.Itoa(h.age) + " years)" }