Go์์ ์์ฃผ ์ฌ์ฉํ๋ reflect ๊ตฌ๋ฌธ (Golang reflect)
๊ธ ์์ฑ์: ๋ฅํด๋ฒ .
๋ฐ์ํ
๊ตฌ์กฐ์ฒด ๋ฐ ์ธํฐํ์ด์ค ์ ์
type Animal interface{
Move(int) bool
}
type Cat struct {
Name string `custom:"name"`
Age int `custom:"age"`
Child []string `custom:"child"`
}
func (c *Cat) Move(distance int) bool {
fmt.Println("Cat Move ", distance)
return true
}
type Dog struct{
Name string `custom:"name"`
Age int `custom:"age"`
Child []string `custom:"child"`
}
func (d *Dog) Move(distance int) bool {
fmt.Println("Dog Move ", distance)
return false
}
๊ตฌ์กฐ์ฒด ํ๋ ์ํ (Iterate Struct Field)
func TestCatFieldLoop(t *testing.T) {
cat := &Cat{
Name: "nabi",
Age: 5,
Child: []string{"nyang", "kong"},
}
LoopObjectField(cat)
}
func LoopObjectField(object interface{}) {
e := reflect.ValueOf(object).Elem()
fieldNum := e.NumField()
for i := 0; i < fieldNum; i ++{
v := e.Field(i)
t := e.Type().Field(i)
fmt.Printf("Name: %s / Type: %s / Value: %v / Tag: %s \n",
t.Name, t.Type, v.Interface(), t.Tag.Get("custom"))
}
}
=== RUN TestCatFieldLoop
Name: Name / Type: string / Value: nabi / Tag: name
Name: Age / Type: int / Value: 5 / Tag: age
Name: Child / Type: []string / Value: [nyang kong] / Tag: child
--- PASS: TestCatFieldLoop (0.00s)
PASS
ํ์ ์ ํตํด ๊ตฌ์กฐ์ฒด ์์ฑ(Create Struct From a Type)
func TestCatCreate(t *testing.T) {
cat := Cat{
Name: "nabi",
Age: 5,
Child: []string{"nyang", "kong"},
}
cat2 := CreateObject(cat).(Cat)
cat2 = Cat {
Name: "nyang",
Age: 1,
}
fmt.Println("Cat1: ", cat)
fmt.Println("Cat2: ", cat2)
}
func CreateObject(object interface{}) interface{}{
e := reflect.TypeOf(object)
return reflect.New(e).Elem().Interface()
}
=== RUN TestCatCreate
Cat1: {nabi 5 [nyang kong]}
Cat2: {nyang 1 []}
--- PASS: TestCatCreate (0.00s)
PASS
ํ์ ์ ํตํด ๊ตฌ์กฐ์ฒด ์์ฑ(Create Struct From a Type) - ํฌ์ธํฐ(Pointer)
func TestCatCreatePointer(t *testing.T) {
cat := &Cat{
Name: "nabi",
Age: 5,
Child: []string{"nyang", "kong"},
}
cat2 := CreateObjectPointer(cat).(*Cat)
cat2.Name = "nyang"
cat2.Age = 1
fmt.Println("Cat1: ", cat)
fmt.Println("Cat2: ", cat2)
}
func CreateObjectPointer(object interface{}) interface{}{
e := reflect.ValueOf(object).Elem()
return reflect.New(e.Type()).Interface()
}
=== RUN TestCatCreatePointer
Cat1: &{nabi 5 [nyang kong]}
Cat2: &{nyang 1 []}
--- PASS: TestCatCreatePointer (0.00s)
PASS
์ฌ๋ผ์ด์ค ํ์ ์ํ(Slice Type Loop)
func TestLoopFieldSliceElement(t *testing.T) {
animals := []Animal{
&Cat{"nyang", 5, []string{"kong"}},
&Dog{"mung", 10, nil},
}
LoopFieldSliceElement(animals)
}
func LoopFieldSliceElement(object interface{}) {
v := reflect.ValueOf(object)
length := v.Len()
for i := 0; i < length; i++ {
LoopObjectField(v.Index(i).Interface())
}
}
func LoopObjectField(object interface{}) {
e := reflect.ValueOf(object).Elem()
fieldNum := e.NumField()
for i := 0; i < fieldNum; i ++{
v := e.Field(i)
t := e.Type().Field(i)
fmt.Printf("Name: %s / Type: %s / Value: %v / Tag: %s \n",
t.Name, t.Type, v.Interface(), t.Tag.Get("custom"))
}
}
=== RUN TestLoopFieldSliceElement
Name: Name / Type: string / Value: nyang / Tag: name
Name: Age / Type: int / Value: 5 / Tag: age
Name: Child / Type: []string / Value: [kong] / Tag: child
Name: Name / Type: string / Value: mung / Tag: name
Name: Age / Type: int / Value: 10 / Tag: age
Name: Child / Type: []string / Value: [] / Tag: child
--- PASS: TestLoopFieldSliceElement (0.00s)
PASS
์ฌ๋ผ์ด์ค๋ฅผ ํตํด ๊ตฌ์กฐ์ฒด ์์ฑ(Create Object From Slice Type)
func TestSliceTypeToObject(t *testing.T) {
cats := []Cat{
{"nyang", 5, []string{"kong"}},
{"kong", 1, nil},
}
cat := CreateObjectFromSlice(cats)
fmt.Printf("%+v\n", cat)
}
func CreateObjectFromSlice(object interface{}) interface{} {
return reflect.New(reflect.ValueOf(object).Index(0).Type()).Interface()
}
=== RUN TestSliceTypeToObject
&{Name: Age:0 Child:[]}
--- PASS: TestSliceTypeToObject (0.00s)
PASS
์ฌ๋ผ์ด์ค๋ฅผ ์ํํ๋ฉด์ ๋ฉ์๋ ํธ์ถ
func TestAnimalMethodCall(t *testing.T) {
animals := []Animal{
&Cat{"nyang", 5, []string{"kong"}},
&Dog{"kong", 1, nil},
}
MethodCall(animals)
}
func MethodCall(object interface{}) {
v := reflect.ValueOf(object)
length := v.Len()
for i := 0; i < length; i++ {
// Method Call
result := v.Index(i).Elem().MethodByName("Move").Call(
[]reflect.Value{
reflect.ValueOf(5),
},
)
// Print Result
fmt.Println(result[0].Interface())
}
}
=== RUN TestAnimalMethodCall
Cat Move 5
true
Dog Move 5
false
--- PASS: TestAnimalMethodCall (0.00s)
PASS
ํ์ ์ ์ ๋ฌํ์ฌ ์ฌ๋ผ์ด์ค๋ฅผ ๋ง๋ค๊ณ json ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅํด ๋ง๋ ์ฌ๋ผ์ด์ค์ append
type Cat struct {
Name string `json:"name"`
Age int `json:"age"`
Child []string `json:"child"`
}
func TestCatDataApply(t *testing.T) {
var cat *Cat
result := DataApply(cat)
cats := *(result.(*[]*Cat))
for _, cat := range cats {
fmt.Println(cat)
}
}
func DataApply(object interface{}) interface{} {
jsonMessage := "{\"name\": \"nyang\", \"age\": 5}"
objType := reflect.TypeOf(object) // Type: *Cat
objSlice:= reflect.New(reflect.SliceOf(objType)).Interface() // *[]*Cat (Create Slice []*Cat)
for i := 0; i < 5; i ++ {
obj := reflect.New(objType.Elem()).Interface() // *Cat (Create Instance Cat)
_ = json.Unmarshal([]byte(jsonMessage), obj) // json data apply
v := reflect.ValueOf(objSlice)
v.Elem().Set(reflect.Append(v.Elem(), reflect.ValueOf(obj)))
}
return objSlice
}
=== RUN TestCatDataApply
&{nyang 5 []}
&{nyang 5 []}
&{nyang 5 []}
&{nyang 5 []}
&{nyang 5 []}
--- PASS: TestCatDataApply (0.00s)
PASS
๋ฐ์ํ
'Language > Go' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Go] ์คํ์ค์ธ ํ๋ก์ธ์ค์ ๋ํด memory dump ํ์ผ์ ๋จ๊ธฐ๊ณ GoLand๋ก ๋ถ์ํ๊ธฐ (0) | 2019.11.05 |
---|---|
Go์์ ์ค์ํ๊ธฐ ์ฌ์ด ์ผ์ด์ค - defer, panic, recover (0) | 2019.04.24 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[Go] ์คํ์ค์ธ ํ๋ก์ธ์ค์ ๋ํด memory dump ํ์ผ์ ๋จ๊ธฐ๊ณ GoLand๋ก ๋ถ์ํ๊ธฐ
[Go] ์คํ์ค์ธ ํ๋ก์ธ์ค์ ๋ํด memory dump ํ์ผ์ ๋จ๊ธฐ๊ณ GoLand๋ก ๋ถ์ํ๊ธฐ
2019.11.05 -
Go์์ ์ค์ํ๊ธฐ ์ฌ์ด ์ผ์ด์ค - defer, panic, recover
Go์์ ์ค์ํ๊ธฐ ์ฌ์ด ์ผ์ด์ค - defer, panic, recover
2019.04.24