Go语言第十九课 反射

Go类型断言

我们常用interface{}类型去接实参,企图实现类型泛型的效果。

例如

func add(a interface{}, b interface{})(c interface){

}

但是在实际处理的时候,我们又希望得到实际的类型这时候我们就可以使用类型断言

情况1:我们知道传入的类型,例如

var a interface = 1

b,flg = a.(int)

此时b必是int型。如果断言成立,则flg为true,b值为1;如果断言失败,则flg为false,b为默认初始值

情况2:我们不知道传入的类型

我们可以采取下文switch  type_flg := input.(type)的方法

指针还是结构,Kind类型

func main() {
	stu := student{"yuyong", 28}
	p_stu := new(student)
	p_stu.stu_name = "benben"
	p_stu.stu_age = 18

	fmt.Println(checkType(stu))
	fmt.Println(checkType(p_stu))
}

func checkType(input interface{}) string {
	iType := reflect.TypeOf(input)
	if iType.Kind() == reflect.Ptr {
		return "this is a fuck ptr"
	}
	if iType.Kind() == reflect.Struct {
		return "this is a fuck struct"
	}
	return "error type"
}

this is a fuck struct
this is a fuck ptr

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值