2020年1月4日 星期六

我的 Go reflect 筆記


package main

import (
"fmt"
"reflect"
)

type S1 struct {
Name string
Age int
}

type S2 struct {
Name string
Info string
}

type S3 struct {
U string
V string
}

type S4 struct {
K string
V string
}

func main() {
s1 := S1{
Name: "s1: oooo",
Age: 10,
}

s2 := S2{
Name: "s2: test",
Info: "s2: qqq",
}

s3 := S3{
U: "s3: 1",
V: "s3: A",
}

fmt.Println("before change: ")
fmt.Println(s1)
testReflect(&s1)
fmt.Println("after change: ")
fmt.Println(s1)
fmt.Println("======")

fmt.Println("before change: ")
fmt.Println(s2)
testReflect(&s2)
fmt.Println("after change: ")
fmt.Println(s2)
fmt.Println("======")

fmt.Println("before change: ")
fmt.Println(s3)
rType := reflect.TypeOf(s3)
rValue := reflect.ValueOf(&s3)

for i := 0; i < rType.NumField(); i++ {
rValue.Elem().Field(i).SetString(fmt.Sprintf("s3: %d", i))
}
fmt.Println("after change: ")
fmt.Println(s3)
fmt.Println("======")

s4 := testReflect(S4{
K: "s4: a000",
V: "s4: p777",
})
fmt.Println(s4)

s4Ptr := testReflect(&S4{
K: "q111",
V: "q222",
})
fmt.Println(s4Ptr)
}

func testReflect(i interface{}) interface{} {
rValueOf := reflect.ValueOf(i)
ret := i

switch i.(type) {
case *S1:
ret := rValueOf.Interface().(*S1)
ret.Name = "*s1: rrrr"
ret.Age = 19
case *S2:
ret := rValueOf.Interface().(*S2)
ret.Name = "*s2: 222"
ret.Info = "*s2: good"
case S3:
s3 := reflect.New(reflect.TypeOf(i))
newS3 := s3.Elem().Interface().(S3)
newS3.U = "s3: test"
newS3.V = "s3: 1234"
return newS3
case S4:
rValue := reflect.ValueOf(&i)
s4 := rValue.Elem().Interface().(S4)
s4.K = "s4: 0"
s4.V = "s4: 1"
return s4
case *S4:
rValue := reflect.ValueOf(i)
for i := 0; i < rValue.Elem().NumField(); i++ {
rValue.Elem().Field(i).SetString(fmt.Sprintf("*s4: %d", i))
}
return rValue
}

return ret
}