duanguanzai6181 2014-07-22 01:35
浏览 53
已采纳

从指向类型的指针创建类型的切片

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
}
  • what should i do to be able to use range on the returned slice?
  • how can i use the itemtyp as the type of my slice?
  • 写回答

2条回答 默认 最新

  • dongqu3623 2014-07-22 02:26
    关注

    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
    }
    

    <kbd>playground</kbd>

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?