1. 程式人生 > >Go語言第十九課 反射

Go語言第十九課 反射

package reflect

import (
	"testing"
	"strconv"
	"fmt"
	"reflect"
)

type student interface {
	getAge() int
	getName() string
}

type schoolchild struct {
	name        string
	age         int
	school_name string
}

func (this *schoolchild) getAge() int {
	return this.age
}

func (this *schoolchild) getName() string {
	return this.name
}

func SPrint(input interface{}) string {
	/*
	input是不定介面型別(即任意介面型別),input.(type)返回的就是特定介面型別
	例如,如果用input指向一個student介面型別,那麼通過input是無法調到student介面函式的(因為interface{}實際上弱化了student介面的功能)
	這時候如果進行input.(type),則返回的就是student型別的介面了(相當於將interface{}強化還原成student)
	*/
	switch  type_flg := input.(type) {
	case student:
		return type_flg.getName()
	case string:
		return type_flg
	case int:
		return strconv.Itoa(type_flg)
	default:
		return "???"
	}
}

func TestReflect(t *testing.T) {
	var yong student
	yong = &schoolchild{"yuyong", 10, "usc"}
	fmt.Println(SPrint(yong))

	//不定介面轉特定介面不能用強轉
	var test_ref interface{} = yong
	fmt.Println(test_ref.(student).getName())

	val := reflect.ValueOf(test_ref)
	//防止出現reflect: call of reflect.Value.NumField on ptr Value [recovered]
	val = val.Elem()
	for i := 0; i < val.NumField(); i++ {
		field_name := val.Type().Field(i).Name
		fmt.Print(field_name + " ")
		fmt.Print(val.Type().Field(i).Type.Name() + " ")
		fmt.Println(val.FieldByName(field_name).String())
	}
}

yuyong
yuyong
name string yuyong
age int <int Value>
school_name string usc