FPGA
FPGA

Reputation: 3865

Create a slice of type from a pointer to a type

Trying to create a slice in which the type is set dynamicaly based on a pointer to a specific type, so i made the following sample

func main() {
    var chicken *Chicken
    //create a slice of chickens
    chickens:=GetaDynamiclyTypedSlice(chicken)

    //this throws  cannot range over chickens (type *[]interface {}) and i cant figure how to create a slice using my above chicken pointer
    for _,chicken := range chickens{
        fmt.Println(chicken)
    }

}

type Chicken struct{
    Weight float64
}

func GetaDynamiclyTypedSlice(ptrItemType interface{})*[]interface {}{
    var collection []interface{}
    itemtyp := reflect.TypeOf(ptrItemType).Elem()
    for i:=0;i<1000;i++{
        //create an item of the wanted type
        item := reflect.New(itemtyp)
        //set a random float to the weight value
        item.Elem().FieldByName("Weight").SetFloat(rnd.ExpFloat64())
        collection = append(collection,&item)
    }
    return &collection
}

Upvotes: 0

Views: 70

Answers (2)

OneOfOne
OneOfOne

Reputation: 99234

There are few problems with your code.

  1. You're returning a pointer to a reflect.Value, 99% sure that's not what you're trying to achive.

  2. You're not dereferencing the slice like Simon mentioned.

  3. Slices are pointer types, if you're returning *[]interface{} for performance reasons, you're actually hurting not helping.

So let's rewrite the code and optimize it! (it's late night SO, time to party):

// pass the size to preallocate the slice, also return the correct slice type.
func GetaDynamiclyTypedSlice(ptrItemType interface{}, size int) (col []interface{}) {
    col = make([]interface{}, size)
    itemtyp := reflect.TypeOf(ptrItemType).Elem()
    for i := range col { //prettier than for i := 0; etc etc
        item := reflect.New(itemtyp)
        item.Elem().FieldByName("Weight").SetFloat(rand.ExpFloat64())
        col[i] = item.Interface() //this is the magic word, return the actual item, not reflect.Value
    }
    return
}

playground

Upvotes: 2

Simon Whitehead
Simon Whitehead

Reputation: 65079

You just need to dereference the pointer (so you're not iterating over a pointer - you're iterating over a slice):

for _, chicken := range *chickens {
    // ...
}

Playground link: http://play.golang.org/p/NBv9sooqEV

Upvotes: 2

Related Questions