无法使用 Golang 中的反射将 xml 解构到动态创建的结构中

这是我用于解析 xml 的代码。在函数的末尾,我应该在值切片中具有结构的字段值。


func FindAttrs(attrs []Tag, errorChan chan<- error) {

    var tableFields []reflect.StructField

    for _, v := range attrs {

        tableFields = append(tableFields, reflect.StructField{

            Name:      strings.Title(v.Name),

            Type:      reflect.TypeOf(""),

            Tag:       reflect.StructTag(fmt.Sprintf(`xml:"%v,attr"`, v.Name)),

            Offset:    0,

            PkgPath:   "utility",

            Index:     nil,

            Anonymous: false,

        })

    }

    unmarshalStruct := reflect.Zero(reflect.StructOf(tableFields))

    err := xml.Unmarshal(ReadBytes(errorChan), &unmarshalStruct)

    HandleError(err, "Error parse config", false, errorChan)

    values := make([]interface{}, unmarshalStruct.NumField())

    for i := 0; i < unmarshalStruct.NumField(); i++ {

        values[i] = unmarshalStruct.Field(0).Interface()

    }

}

但是,它会惊慌失措地显示以下消息:


reflect.Value.Interface: cannot return value obtained from unexported field or method

我称之为:


utility.FindAttrs([]utility.Tag{

        {"name", reflect.String}, {"isUsed", reflect.String},

    }, errorChan)

我的xml是<configuration name="mur" isUsed="mur"/>


慕侠2389804
浏览 136回答 1
1回答

慕少森

需要制作一个指向结构的指针而不是一个值,并将指针的值(可以通过检索到的函数)传递给Unmarshal而不是它本身。Interface()var tableFields []reflect.StructField&nbsp; &nbsp; for _, v := range attrs {&nbsp; &nbsp; &nbsp; &nbsp; tableFields = append(tableFields, reflect.StructField{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Name: strings.Title(v.Name),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Type: reflect.TypeOf(""),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Tag:&nbsp; reflect.StructTag(fmt.Sprintf(`xml:"%v,attr"`, v.Name)),&nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; }&nbsp; &nbsp; rv := reflect.New(reflect.StructOf(tableFields)) // initialize a pointer to the struct&nbsp; &nbsp; v := rv.Interface() // get the actual value&nbsp; &nbsp; err := xml.Unmarshal([]byte(`<configuration name="foo" isUsed="bar"/>`), v)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; panic(err)&nbsp; &nbsp; }&nbsp; &nbsp; rv = rv.Elem() // dereference the pointer&nbsp; &nbsp; values := make([]interface{}, rv.NumField())&nbsp; &nbsp; for i := 0; i < rv.NumField(); i++ {&nbsp; &nbsp; &nbsp; &nbsp; values[i] = rv.Field(i).Interface()&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go