为了账号安全,请及时绑定邮箱和手机立即绑定

golang中参数中的动态结构

golang中参数中的动态结构

Go
萧十郎 2022-05-10 14:06:48
我必须处理许多不同域的文件,但它们都有行固定位置我为具有起始位置和结束位置标签的域创建结构type IP0059T1 struct {    TableID                            string `startpos:"1" endpos:"8"`    EffectiveDateTime                  string `startpos:"11" endpos:"11"`}type IP0059T2 struct {    TableID                            string `startpos:"1" endpos:"8"`    SequenceNumber                  string `startpos:"11" endpos:"14"`}我创建了一个方法,它适用于一个表func (s *Service) GetIP0059T01(bundleURI string) ([]IP0059T1, error) {    reader := getReader(bundleURI)    var items []IP0059T1    err = patterns.Each(reader, func(e *contract.Entry) error {        line := string(e.Data)        var item = new(IP0059T1)        structName := reflect.TypeOf(item).Name()        structValues := reflect.ValueOf(item).Elem()        for i := 0; i < structValues.NumField(); i++ { // iterates through every struct type field            field := structValues.Field(i) // returns the content of the struct type field            value, _ := getValue(line, structValues.Type().Field(i), structName)            _ = s.SetValue(field, structValues, i, structName, value)        }        items = append(items, *item)        return nil    })    if err != nil {        return nil, err    }    return items, nil}setValue 使用反射func setValue(field reflect.Value, structValues reflect.Value, i int, structName string, value string) error {    if field.Kind() != reflect.String {        return &FieldNotStringError{Field: structValues.Type().Field(i).Name, Struct: structName}    }    field.SetString(value)    return nil}还 getValue 使用反射func getValue(line string, field reflect.StructField, structName string) (string, error) {    startPosition, _ := strconv.Atoi(field.Tag.Get("startpos"))    endPosition, _ := strconv.Atoi(field.Tag.Get("endpos"))    return line[(startPosition - 1):(endPosition)], nil}那么,将方法 GetIP0059T01 转换为具有获取 uri 和类型的泛型方法并返回一个可以转换为我传递的类型的数组的接口数组有什么解决方法吗?基本上,我想要一个通用的东西
查看完整描述

2 回答

?
慕容3067478

TA贡献1773条经验 获得超3个赞

看起来您真正需要该类型的唯一两个地方是分配它时以及将其附加到数组时。因此,您可以更改函数以获取两个回调:


func GetStuff(bundleURI string, newItem func() interface{},collect func(interface{})) error {


   // instead of var item = new(IP0059T1)

   var item = newItem()


   ...


   // instead of items = append(items, *item)

   collect(item)



}

并使用以下方法调用该函数:


items:=make([]Item,0)

GetStuff(uri, func() interface{} {return new(Item)}, 

func(item interface{}) {items=append(items,*item.(*Item))})


查看完整回答
反对 回复 2022-05-10
?
catspeake

TA贡献1111条经验 获得超0个赞

你可以像 Go 标准库那样做,例如 in encoding/json,就是把要填写的值作为参数。您的“通用”将类似于:


GetValues(bundleURI string, dest interface{}) (error)

wheredest应该是指向应该反序列化为任何类型的切片的指针,例如:


var v []IP0059T1

err = GetValues(myURI, &v)

然后,GetValues您可以使用reflect.Type.Elem()获取切片元素的类型,reflect.New()创建该类型的新实例,reflect.Append()并将它们直接附加到dest. 这保留了类型安全,同时允许某种程度的泛型编程。


查看完整回答
反对 回复 2022-05-10
  • 2 回答
  • 0 关注
  • 144 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信