1. 对切片的操作
Slice():对切片再切片(两下标)
Slice() 函数与上面所有类型转换的函数都不一样,它返回还是 reflect.Value 反射对象,而不再是我们所想的真实世界里的切片对象。
通过以下示例代码可验证
package main
import (
"fmt"
"reflect"
)
func main() {
var numList []int = []int{1,2}
v1 := reflect.ValueOf(numList)
fmt.Printf("转换前, type: %T, value: %v \n", v1, v1)
// Slice 函数接收两个参数
v2 := v1.Slice(0, 2)
fmt.Printf("转换后, type: %T, value: %v \n", v2, v2)
}
输出如下
转换前, type: reflect.Value, value: [1 2]
转换后, type: reflect.Value, value: [1 2]
Slice3():对切片再切片(三下标)
Slice3() 与 Slice() 函数一样,都是对一个切片的反射对象
Set() 和 Append():更新切片
示例代码如下
package main
import (
"fmt"
"reflect"
)
func appendToSlice(arrPtr interface{}) {
valuePtr := reflect.ValueOf(arrPtr)
value := valuePtr.Elem()
value.Set(reflect.Append(value, reflect.ValueOf(3)))
fmt.Println(value)
fmt.Println(value.Len())
}
func main() {
arr := []int{1,2}
appendToSlice(&arr)
fmt.Println(arr)
}
输出如下
3
[1 2 3]
[1 2 3]
2. 对属性的操作
NumField() 和 Field()
package main
import (
"fmt"
"reflect"
)
type Person struct {
name string
age int
gender string
}
func (p Person)SayBye() {
fmt.Println("Bye")
}
func (p Person)SayHello() {
fmt.Println("Hello")
}
func main() {
p := Person{"写代码的明哥", 27, "male"}
v := reflect.ValueOf(p)
fmt.Println("字段数:", v.NumField())
fmt.Println("第 1 个字段:", v.Field(0))
fmt.Println("第 2 个字段:", v.Field(1))
fmt.Println("第 3 个字段:", v.Field(2))
fmt.Println("==========================")
// 也可以这样来遍历
for i:=0;i<v.NumField();i++{
fmt.Printf("第 %d 个字段:%v \n", i+1, v.Field(i))
}
}
输出如下
字段数: 3
第 1 个字段: 写代码的明哥
第 2 个字段: 27
第 3 个字段: male
==========================
第 1 个字段:写代码的明哥
第 2 个字段:27
第 3 个字段:male
3. 对方法的操作
NumMethod() 和 Method()
要获取 Name ,注意使用使用 TypeOf
package main
import (
"fmt"
"reflect"
)
type Person struct {
name string
age int
gender string
}
func (p Person)SayBye() {
fmt.Println("Bye")
}
func (p Person)SayHello() {
fmt.Println("Hello")
}
func main() {
p := &Person{"写代码的明哥", 27, "male"}
t := reflect.TypeOf(p)
fmt.Println("方法数(可导出的):", t.NumMethod())
fmt.Println("第 1 个方法:", t.Method(0).Name)
fmt.Println("第 2 个方法:", t.Method(1).Name)
fmt.Println("==========================")
// 也可以这样来遍历
for i:=0;i<t.NumMethod();i++{
fmt.Printf("第 %d 个方法:%v \n", i+1, t.Method(i).Name)
}
}
输出如下
方法数(可导出的): 2
第 1 个方法: SayBye
第 2 个方法: SayHello
==========================
第 1 个方法:SayBye
第 2 个方法:SayHello
4. 动态调用函数(使用索引且无参数)
要调用 Call,注意要使用 ValueOf
package main
import (
"fmt"
"reflect"
)
type Person struct {
name string
age int
}
func (p Person)SayBye() string {
return "Bye"
}
func (p Person)SayHello() string {
return "Hello"
}
func main() {
p := &Person{"wangbm", 27}
t := reflect.TypeOf(p)
v := reflect.ValueOf(p)
for i:=0;i<v.NumMethod();i++{
fmt.Printf("调用第 %d 个方法:%v ,调用结果:%v\n",
i+1,
t.Method(i).Name,
v.Elem().Method(i).Call(nil))
}
}
输出如下
调用第 1 个方法:SayBye ,调用结果:[Bye]
调用第 2 个方法:SayHello ,调用结果:[Hello]
5. 动态调用函数(使用函数名且无参数)
package main
import (
"fmt"
"reflect"
)
type Person struct {
name string
age int
gender string
}
func (p Person)SayBye() {
fmt.Print("Bye")
}
func (p Person)SayHello() {
fmt.Println("Hello")
}
func main() {
p := &Person{"写代码的明哥", 27, "male"}
v := reflect.ValueOf(p)
v.MethodByName("SayHello").Call(nil)
v.MethodByName("SayBye").Call(nil)
}
6. 动态调用函数(使用函数且有参数)
package main
import (
"fmt"
"reflect"
)
type Person struct {
}
func (p Person)SelfIntroduction(name string, age int) {
fmt.Printf("Hello, my name is %s and i'm %d years old.", name, age)
}
func main() {
p := &Person{}
//t := reflect.TypeOf(p)
v := reflect.ValueOf(p)
name := reflect.ValueOf("wangbm")
age := reflect.ValueOf(27)
input := []reflect.Value{name, age}
v.MethodByName("SelfIntroduction").Call(input)
}
输出如下
Hello, my name is wangbm and i'm 27 years old.