英文:
Decode XML into interface type with Go?
问题
在Go 1.3中,将XML解码为接口类型是可能的吗?
例如,如果结构体看起来像这样(简化):
type Field interface { ... }
// DataField和ControlField满足Field接口
type DataField struct { ... } // <- 一个具体类型,带有XML标签
type ControlField struct { ... } // <- 另一个具体类型,带有XML标签
type Record struct {
Fields []Field // <- Field是一个接口
}
...
// 我们想要解码为一个record,例如:
var record Record
decoder.DecodeElement(&record, &se)
...
据我所见,使用具体类型解码XML是可行的,例如:
type Record struct {
ControlFields []ControlField // <- 使用具体类型可以工作
DataFields []DataField // <- 使用具体类型可以工作
}
但是,使用接口类型会失败,尽管实现已经用正确的XML标签进行了注释。
可运行的示例,请参见http://play.golang.org/p/tPlw4Y74tt或gist。
英文:
Is it possible to decode XML into an interface type with Go 1.3?
For example, if the structs look something like this (simplified):
<!-- language: lang-go -->
type Field interface { ... }
// DataField and ControlField satisfy Field interface
type DataField struct { ... } // <- One concrete type, with XML tags
type ControlField struct { ... } // <- Another concrete type, with XML tags
type Record struct {
Fields []Field // <- Field is an interface
}
...
// we want to decode into a record, e.g.
var record Record
decoder.DecodeElement(&record, &se)
...
As far as I can see, it is possible to decode XML with the concrete types, e.g.:
<!-- language: lang-go -->
type Record struct {
ControlFields []ControlField // <- Using concrete type works
DataFields []DataField // <- Using concrete type works
}
But the interface type fails, although the implementations are annotated with the correct XML tags.
For a runnable example, see http://play.golang.org/p/tPlw4Y74tt or as gist.
答案1
得分: 1
从查看encoding/xml
包中的代码来看,似乎接口类型被简单地跳过了:
...
switch v := val; v.Kind() {
case reflect.Interface:
// TODO: 目前,只是简单地忽略该字段。在不久的将来,如果不为nil,我们可能会选择对其进行解组。
return p.Skip()
...
Go版本:1.3。
英文:
From looking at the code in the encoding/xml
package, it seems, interface types are just skipped:
...
switch v := val; v.Kind() {
case reflect.Interface:
// TODO: For now, simply ignore the field. In the near
// future we may choose to unmarshal the start
// element on it, if not nil.
return p.Skip()
...
Go version: 1.3.
答案2
得分: 1
你需要使用某种具体类型来初始化接口数组中的值,否则 XML 将无法推断出你所指的类型是什么:
http://play.golang.org/p/6LVgK7rza9
// InterfaceRecord 失败
record := InterfaceRecord{
Fields: []Field{&DataField{}},
}
decoder.DecodeElement(&record, &se)
output, err := xml.MarshalIndent(record, " ", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
}
os.Stdout.Write(output)
输出结果:
<record>
<d tag=""></d>
</record>
英文:
You need to initialize the values inside your interface arrays with some concrete type or xml will not be able to infer to which type are you referring to:
http://play.golang.org/p/6LVgK7rza9
// InterfaceRecord fails
record := InterfaceRecord{
Fields: []Field{&DataField{}},
}
decoder.DecodeElement(&record, &se)
output, err := xml.MarshalIndent(record, " ", " ")
if err != nil {
fmt.Printf("error: %v\n", err)
}
os.Stdout.Write(output)
Output:
<record>
<d tag=""></d>
</record>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论