dongxie9448 2018-08-28 14:03
浏览 13
已采纳

如何将更多项目添加到各种类型的切片中

I want to be able to pass a slice of a particular type into a function that will populate it with more items of that type. Here is an example of code does not compile, but describes what I want to achieve:

package main

import (
  "log"
  "reflect"
  "strings"
)
type Person struct {
  Name,Hobbies string
}
type Cat struct {
  Name,FurColor string
}
func main() {

  people := []Person{}
  createThings(&people,10)
  log.Println(people)

  cats := []Cat{}
  createThigns(&cats,5)
  log.Println(cats)
}
func createThings(slice interface{},num int) {
  b := strings.Replace(reflect.TypeOf(slice).String(),"*[]main.","",-1)
  log.Println(b)
  for c:=0;c<num;c++ {
    eval("item := "+b+"{}")
    *slice = append(*slice,item)
  }
}

Essentially, the statement eval("item := "+b+"{}") is what I would have done in other programming languages that allow it, but from what I understand, it's not something idomatic to golang.

I've seen something similar in the documentation for http://gorm.io where you can do something like this:

cats := []Cat{}
db.Find(&cats)
people :=[]Person{}
db.Find(&people)

The gorm object will add more records to cats or people even though they are completely different types. I had a hard time digging into the gorm code to see how they do this.

I wanted to know how I can change my createThings function so that it can take a slice of anything, and then add more empty records to it. (Later, I'll use reflection to determine what fields are available in the structs, and populate with random data for the purposes of a game I'm making.)

  • 写回答

1条回答 默认 最新

  • doujiang2641 2018-08-28 14:11
    关注

    Use the reflect package to append elements to a slice of any type.

    func createThings(slicep interface{}, num int) {
        // Get reflect value for the slice. 
        // The call to Elem() deferences the pointer.
        v := reflect.ValueOf(slicep).Elem()
    
        // Create a zero value using the slice element type.
        z := reflect.Zero(v.Type().Elem())
    
        for c := 0; c < num; c++ {
            // Append zero value to slice.
            v.Set(reflect.Append(v, z))
        }
    }
    

    Run it on the playground.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥35 平滑拟合曲线该如何生成
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决