您的位置 首页 golang

go语言学习总结(二十九)Golang的反射

1.反射的简介

Golang提供了一种机制,在编译时不知道类型的情况下,可更新变量、运行时查看值、调用方法以及直接对他们的布局进行操作的机制,称为反射。

2.为什么使用反射?

打个比方,有时候我们需要一个函数可以处理各种类型的值。在不知道类型的情况下,你可能会这么写:

// 伪代码

switch value := value.(type) {

case string:

// …一些操作

case int:

// …一些操作

case cbsStruct: // 自定义的结构体

// …一些操作

// …

}

有没发现什么问题?

这边存在一个问题:类型很多,这个函数会写的非常长,而且还可能存在自定的类型,也就是说这个判断日后可能还要一直改,因为无法知道未知值到底属于什么类型。

无法透视一个未知类型的时候,以上代码其实不是很合理,这时候就需要有反射来帮忙你处理,反射使用TypeOf和ValueOf函数从接口中获取目标对象的信息,轻松完成目的。

3.反射具体能做什么?

1.获取变量内部信息

reflect提供了两种类型来进行访问接口变量的内容:

reflect.ValueOf() 获取输入参数接口中的数据的值,如果为空则返回0 <- 注意是0

reflect.TypeOf() 动态获取输入参数接口中的值的类型,如果为空则返回nil <- 注意是nil

package main

import (

“fmt”

“reflect”

)

func main() {

var name string = “咖啡色的羊驼”

// TypeOf会返回目标数据的类型,比如int/float/struct/指针等

reflectType := reflect.TypeOf(name)

// valueOf返回目标数据的的值,比如上文的”咖啡色的羊驼”

reflectValue := reflect.ValueOf(name)

fmt.Println(“type: “, reflectType)

fmt.Println(“value: “, reflectValue)

}

更深一层:在以上操作发生的时候,反射将“接口类型的变量”转为了“反射的接口类型的变量”,比如上文实际上返回的是reflect.Value和reflect.Type的接口对象。(可以根据ide跟踪一下相关函数返回类型便知)

2.struct的反射

package main

import (

“fmt”

“reflect”

)

type Student struct {

Id int

Name string

}

func (s Student) Hello(){

fmt.Println(“我是一个学生”)

}

func main() {

s := Student{Id: 1, Name: “咖啡色的羊驼”}

// 获取目标对象

t := reflect.TypeOf(s)

// .Name()可以获取取这个类型的名称

fmt.Println(“这个类型的名称是:”, t.Name())

// 获取目标对象的值类型

v := reflect.ValueOf(s)

// .NumField()来获取其包含的字段的总数

for i := 0; i < t.NumField(); i++ {

// 从0开始获取Student所包含的key

key := t.Field(i)

// 通过interface方法来获取key所对应的值

value := v.Field(i).Interface()

fmt.Printf(“第%d个字段是:%s:%v = %v n”, i+1, key.Name, key.Type, value)

}

// 通过.NumMethod()来获取Student里头的方法

for i:=0;i<t.NumMethod(); i++ {

m := t.Method(i)

fmt.Printf(“第%d个方法是:%s:%vn”, i+1, m.Name, m.Type)

}

}

3.匿名或嵌入字段的反射

package main

import (

“reflect”

“fmt”

)

type Student struct {

Id int

Name string

}

type People struct {

Student // 匿名字段

}

func main() {

p := People{Student{Id: 1, Name: “咖啡色的羊驼”}}

t := reflect.TypeOf(p)

// 这里需要加一个#号,可以把struct的详情都给打印出来

// 会发现有Anonymous:true,说明是匿名字段

fmt.Printf(“%#vn”, t.Field(0))

// 取出这个学生的名字的详情打印出来

fmt.Printf(“%#vn”, t.FieldByIndex([]int{0, 1}))

// 获取匿名字段的值的详情

v := reflect.ValueOf(p)

fmt.Printf(“%#vn”, v.Field(0))

}

4.判断传入的类型是否是我们想要的类型

package main

import (

“reflect”

“fmt”

)

type Student struct {

Id int

Name string

}

func main() {

s := Student{Id: 1, Name: “咖啡色的羊驼”}

t := reflect.TypeOf(s)

// 通过.Kind()来判断对比的值是否是struct类型

if k := t.Kind(); k == reflect.Struct {

fmt.Println(“bingo”)

}

num := 1;

numType := reflect.TypeOf(num)

if k := numType.Kind(); k == reflect.Int {

fmt.Println(“bingo”)

}

}

5.通过反射修改内容

package main

import (

“reflect”

“fmt”

)

type Student struct {

Id int

Name string

}

func main() {

s := &Student{Id: 1, Name: “咖啡色的羊驼”}

v := reflect.ValueOf(s)

// 修改值必须是指针类型否则不可行

if v.Kind() != reflect.Ptr {

fmt.Println(“不是指针类型,没法进行修改操作”)

return

}

// 获取指针所指向的元素

v = v.Elem()

// 获取目标key的Value的封装

name := v.FieldByName(“Name”)

if name.Kind() == reflect.String {

name.SetString(“小学生”)

}

fmt.Printf(“%#v n”, *s)

// 如果是整型的话

test := 888

testV := reflect.ValueOf(&test)

testV.Elem().SetInt(666)

fmt.Println(test)

}

6.通过反射调用方法

package main

import (

“fmt”

“reflect”

)

type Student struct {

Id int

Name string

}

func (s Student) EchoName(name string){

fmt.Println(“我的名字是:”, name)

}

func main() {

s := Student{Id: 1, Name: “咖啡色的羊驼”}

v := reflect.ValueOf(s)

// 获取方法控制权

// 官方解释:返回v的名为name的方法的已绑定(到v的持有值的)状态的函数形式的Value封装

mv := v.MethodByName(“EchoName”)

// 拼凑参数

args := []reflect.Value{reflect.ValueOf(“咖啡色的羊驼”)}

// 调用函数

mv.Call(args)

}

##4.反射的一些小点

1.使用反射时需要先确定要操作的值是否是期望的类型,是否是可以进行“赋值”操作的,否则reflect包将会毫不留情的产生一个panic。

2.反射主要与Golang的interface类型相关,只有interface类型才有反射一说。如果有兴趣可以看一下TypeOf和ValueOf,会发现其实传入参数的时候已经被转为接口类型了。

// 以下为截取的源代码

func TypeOf(i interface{}) Type {

eface := *(*emptyInterface)(unsafe.Pointer(&i))

return toType(eface.typ)

}

func ValueOf(i interface{}) Value {

if i == nil {

return Value{}

}

escapes(i)

return unpackEface(i)

}

go语言学习总结(二十九)Golang的反射

文章来源:智云一二三科技

文章标题:go语言学习总结(二十九)Golang的反射

文章地址:https://www.zhihuclub.com/86689.shtml

关于作者: 智云科技

热门文章

评论已关闭

28条评论

  1. 1999; 59 1391 1399 Body fluids should not be handled by a woman who is pregnant or who may become pregnant

  2. I started femara in June of 2009 and initially I really had a tough time joint stiffness, stiffness in my hands and feet

  3. Other cytochrome P450 enzymes, such as CYP1A2, CYP2D6, CYP2C9, and CYP2C19, play a minor role in its metabolism

  4. Only one patient was prescribed myeloid growth factor support at some point during therapy 7 cycles, 2

  5. The rates of mastectomy, post lumpectomy radiation and chemotherapy were higher for DCISMi than DCIS 40

  6. In perichondrial tissues, Ihh signaling would be abnormally high and widespread, triggering excessive intramembranous bone deposition and ectopic cartilage formation Vincent KXJLDYnqAriti 5 19 2022

  7. Goldstein, chairman of the international jury of researchers that selects recipients of the Lasker Awards, and recipient of the Lasker Award for Basic Medical Research and the Nobel Prize in Medicine in 1985

  8. A further 2 years later she was found to be anaemic with a positive Coombs test 1 1024 and antibodies against IgG and complement I have now been on them for almost 4 years

  9. A C Brightfield A, fluorescent with FRITC filter B, and with FITC filter C illuminations of a targeted DRN 5 HT neuron

  10. Our results show a wide range of distinct, but related mechanisms, with a prominent role for proliferation related genes and CCND1 in particular Managing blood sugar levels requires round the clock does kidney dialysis affect blood sugar count attention for people diagnosed with diabetes

  11. Be careful and be sure to specify the information on the section Incompatibilities in the instructions to the drug Tamoxifeno Farmoz 20 mg Comprimidos directly from the package or from the pharmacist at the pharmacy arava cipralex 60 mg North Korea has not commented on the seizure, during which 35 North Koreans were arrested after resisting police efforts to intercept the ship in Panamanian waters last week, according to Martinelli

  12. 10 million, will compensate him for it Meta analyses of randomized clinical trials have highlighted the possible association between antihypertensive therapy and both intrauterine growth restriction IUGR and small for gestational age birthweight SGA 2, especially with the use of beta blockers ОІb 3

  13. Leptin induced signals comprise several pathways commonly triggered by many cytokines i

  14. The effects of various meal frequency strategies on total and LDL cholesterol are reported in Table 2 Human enhancement drug use differs from other forms of drug use by virtue of the motivation or purpose of their use

  15. fosphenytoin decreases levels of ospemifene by affecting hepatic intestinal enzyme CYP3A4 metabolism

  16. Total proteins were extracted by directly lysing the cells in Co IP lysis buffer 100 mmol L NaCl, 50 mmol L Tris pH 7 Sometimes your doctor might perform a biopsy by removing a small piece of your skin and having the lab examine it

  17. Genetic relatedness with previous ceftriaxone resistant isolates of Neisseria gonorrhoeae case imported from Premenopausal, hormone receptor positive patient Histologically verified minimally invasive breast cancer, local radical treatment 0 9 involved axillary lymph nodes 10 histologically examined nodes Tumor stage pT1b 3, yT0 or yT1a

  18. Your local Planned Parenthood health center can also help you find fertility testing in your area

  19. Glomerular and tubular effects of ionic and nonionic contrast media diatrizoate and iopamidol

  20. Although mycophenolic acid alone prevents extensive growth of most cells, the addition of aminopterin, which blocks de novo synthesis of IMP, the first purine nucleotide intermediate, ensures complete inhibition of de novo synthesis of all purines

  21. In the wild, the flock groupings likely change quite a bit on a daily basis and maybe change a lot even throughout the day, with what is technically known as fission fusion behavior birds travel in small groups of four or five, foraging together, often joining many other small groups at watering holes or particularly rich food sources for parts of the day, then split up again into the smaller groups

网站地图