Skip to content

Instantly share code, notes, and snippets.

@kjk
Created August 31, 2018 04:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kjk/f67b4bf6042a4499bed28557740b9554 to your computer and use it in GitHub Desktop.
Save kjk/f67b4bf6042a4499bed28557740b9554 to your computer and use it in GitHub Desktop.
How to create a reflect slice
package main
import (
"fmt"
"log"
"reflect"
)
type S struct {
N int
Str string
}
func testMap() {
m := map[reflect.Value]bool{}
s := &S{5, "foo"}
s2 := &S{5, "foo"}
rv1 := reflect.ValueOf(s)
rv12 := reflect.ValueOf(s)
rv2 := reflect.ValueOf(s2)
fmt.Printf("rv1 == rv12: %v\n", rv1 == rv12)
fmt.Printf("rv1 == rv2: %v\n", rv1 == rv2)
m[rv1] = true
fmt.Printf("m[rv1]: %v\n", m[rv1])
fmt.Printf("m[rv12]: %v\n", m[rv12])
fmt.Printf("m[rv2]: %v\n", m[rv2])
}
func fillStruct(results interface{}) error {
rv := reflect.ValueOf(results)
if rv.Type().Kind() != reflect.Ptr {
return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %s. tp: %s", rv.Type().String(), rv.Type().String())
}
sliceV := rv.Elem()
if sliceV.Type().Kind() != reflect.Slice {
return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %s. sliceV.Type(): %s", rv.Type().String(), sliceV.Type().String())
}
// slice element should be a pointer to a struct
sliceElemPtrType := sliceV.Type().Elem()
if sliceElemPtrType.Kind() != reflect.Ptr {
return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %s. sliceElemPtrType: %s", rv.Type().String(), sliceElemPtrType.String())
}
sliceElemType := sliceElemPtrType.Elem()
if sliceElemType.Kind() != reflect.Struct {
return fmt.Errorf("results should be a pointer to a slice of pointers to struct, is %s. sliceElemType: %s", rv.Type().String(), sliceElemType.String())
}
fmt.Printf("tp: %s, is nil: %v\n", rv.Type().String(), sliceV.IsNil())
// if this is a pointer to nil slice
if sliceV.IsNil() {
sliceV.Set(reflect.MakeSlice(sliceV.Type(), 0, 0))
}
v := reflect.New(sliceElemType)
sliceV2 := reflect.Append(sliceV, v)
v = reflect.New(sliceElemType)
sliceV2 = reflect.Append(sliceV2, v)
sliceV.Set(sliceV2)
return nil
}
func testFillStruct1() {
var a []*S
err := fillStruct(&a)
if err != nil {
log.Fatalf("fillStruct() failed with %s\n", err)
}
fmt.Printf("a: %v\nlen(a): %d\n", a, len(a))
}
func testFillStruct2() {
var a = []*S{}
err := fillStruct(&a)
if err != nil {
log.Fatalf("fillStruct() failed with %s\n", err)
}
fmt.Printf("a: %v\nlen(a): %d\n", a, len(a))
}
func main() {
//testFillStruct1()
//testFillStruct2()
testMap()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment