>该文章始发于公众号【迈莫coding】
>链接:[https://mp.weixin.qq.com/s/vFt06c9herwTrx1LTxNaKg](https://mp.weixin.qq.com/s/vFt06c9herwTrx1LTxNaKg)
> go发射第一弹【typeOf使用】
> 链接:[https://mp.weixin.qq.com/s/F8yZyqC5UwoewsX0THqy1w](https://mp.weixin.qq.com/s/F8yZyqC5UwoewsX0THqy1w)
> go反射第二弹【valuef使用】
> 链接:[https://mp.weixin.qq.com/s/lgZykTL8ls6aG0OMNSbZMw](https://mp.weixin.qq.com/s/lgZykTL8ls6aG0OMNSbZMw)
# 目录
- isNil()/isValid()
- 反射创建对象
- Call()函数
- 闲聊
- 欢迎加入我的公众号【迈莫coding】 一起pk大厂
# isNil()/isValid()
go语言中,通过 reflect.ValueOf() 方法获取 reflect.Value 对象时,在reflect.Value 对象中提供了一些方法用来判断值是否为空,如下表所示:
**示例**
```go
package main
import (
"fmt"
"reflect"
)
type User struct{
Name string
Age int
}
func main(){
user := &User{
Name : "迈莫coding",
}
values := reflect.ValueOf(user)
fmt.Println("user对象是否为空:", values.IsNil())
values = values.Elem()
fmt.Println("Name字段属性是否存在:", values.FieldByName("Name").IsValid())
}
```
**结果:**
```go
user对象是否为空: false
Name字段属性是否存在: true
```
**代码说明:**
```go
- 第11行:实例化User对象
- 第15行:判断反射对象values是否为空
- 第17行:判断反射对象中"Name"字段属性是否有效
```
# 反射创建对象
在go语言中,若已知 reflect.Type 类型时,可以通过 reflect.New() 方法进行反射创建实例,但参数注意的是,只能传入 reflect.Type 类型对象。
**示例**
```go
package main
import (
"fmt"
"reflect"
)
type User struct{
Name string
}
func main() {
types := reflect.TypeOf(&User{})
values := reflect.New(types)
fmt.Println("反射创建出对象的类型和种类:", values.Type(), values.Kind())
}
```
**结果**
```go
反射创建出对象的类型和种类: **main.User ptr
```
# Call()函数
如果反射值对象(reflect.Value)中值的类型为函数时,可以通过 reflect.Value 调用该函数。使用反射调用函数时,需要将参数使用反射值对象的切片 []reflect.Value 构造后传入 Call() 方法中,调用完成时,函数的返回值通过 []reflect.Value 返回。
示例
```go
package main
import (
"fmt"
"import"
)
func add(x, y int) int {
return x + y
}
func main() {
addValue := reflect.ValueOf(add)
// 构造函数参数, 传入两个整型值
paramList := []reflect.Value{reflect.ValueOf(10), reflect.ValueOf(20)}
// 反射调用函数
retList := funcValue.Call(paramList)
// 获取第一个返回值, 取整数值
fmt.Println(retList[0].Int())
}
```
**代码说明如下:**
```go
第 9~12 行:定义一个普通的加法函数。
第 17 行:将 add 函数包装为反射值对象。
第 20 行:将 10 和 20 两个整型值使用 reflect.ValueOf 包装为 reflect.Value,再将反射值对象的切片 []reflect.Value 作为函数的参数。
第 23 行:使用 funcValue 函数值对象的 Call() 方法,传入参数列表 paramList 调用 add() 函数。
第 26 行:调用成功后,通过 retList[0] 取返回值的第一个参数,使用 Int 取返回值的整数值。
```
**提示**
反射调用函数的过程需要构造大量的 reflect.Value 和中间变量,对函数参数值进行逐一检查,还需要将调用参数复制到调用函数的参数内存中。调用完毕后,还需要将返回值转换为 reflect.Value,用户还需要从中取出调用值。因此,反射调用函数的性能问题尤为突出,不建议大量使用反射函数调用。
# 闲聊
- 读完文章,自己是不是和反射的cp率又提高了
- 我是迈莫,欢迎大家和我交流
> 觉得文章写得不错的小伙伴,点个赞👍 鼓励一下吧~
# 欢迎加入我的公众号【迈莫coding】 一起pk大厂
**- 迈莫coding欢迎客官的到来**
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210113132234996.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMDY2MDY2,size_16,color_FFFFFF,t_70#pic_center)
有疑问加站长微信联系(非本文作者))