英文:
Unmarshalling optional float64 field returns error on Go
问题
我的翻译如下:
我的应用程序使用的外部API有时会在float64字段中返回空值。当发生这种情况时,我无法解析文档的其余部分。
以下是Go Playground中的示例代码:
package main
import (
"encoding/xml"
"fmt"
)
func main() {
type Result struct {
XMLName xml.Name `xml:"Person"`
Grade float64 `xml:"grade"`
Name string `xml:"name"`
}
data := `
<Person>
<grade/>
<name>Jack</name>
</Person>
`
var v Result
err := xml.Unmarshal([]byte(data), &v)
if err != nil {
fmt.Printf("error: %v", err)
return
}
fmt.Printf("name: %s\n", v.Name)
}
如果我将第12行的float64更改为string,它将正常工作。有什么办法可以解决这个问题吗?我应该将每个字段都定义为string并手动进行转换吗?
英文:
The external API that my application is using, sometimes returns no values for one of the float64 fields. When that happens, I cannot unmarshal the rest of the document.
Here is the sample code in Go playground:
http://play.golang.org/p/Twv8b6KCtw
package main
import (
"encoding/xml"
"fmt"
)
func main() {
type Result struct {
XMLName xml.Name `xml:"Person"`
Grade float64 `xml:"grade"`
Name string `xml:"name"`
}
data := `
<Person>
<grade/>
<name>Jack</name>
</Person>
`
var v Result
err := xml.Unmarshal([]byte(data), &v)
if err != nil {
fmt.Printf("error: %v", err)
return
}
fmt.Printf("name: %s\n", v.Name)
}
If I change float64 in line 12 to string, it will work. Any idea how I can get a workaround for this? Should I just define every field as string and do the conversion manually?
答案1
得分: 4
我相信你发现了一个错误,你应该在问题跟踪器上报告它,我已经提交了一个错误报告问题 8333。
现在针对当前的问题,你有两个选项:
- 使用
string
类型,根据需要自己将其转换为浮点数。 - 完全删除
<grade/>
标签,并在你的结构体中使用xml:"grade,omitempty"
。
英文:
I believe you have discovered a bug, <s>you should report it on the issue tracker</s>, I submitted a bug report issue 8333.
Now for the current problem, you have 2 options:
- Use
string
type they do your own conversation to float on demand. - Remove the
<grade/>
tag completely and usexml:"grade,omitempty"
in your struct.
答案2
得分: 4
为了补充OneOfOne的解决方案,你还可以定义自己的UnmarshalXML
方法。
示例(在play中查看):
type Grade float64
func (g *Grade) UnmarshalXML(d *xml.Decoder, s xml.StartElement) error {
for tok, err := d.Token(); err != io.EOF; tok, err = d.Token() {
if chrdata, ok := tok.(xml.CharData); ok {
f, err := strconv.ParseFloat(string(chrdata), 64)
if err != nil {
return err
}
*(*float64)(g) = f
}
}
return nil
}
type Result struct {
XMLName xml.Name `xml:"Person"`
Grade Grade `xml:"grade"`
Name string `xml:"name"`
}
这段代码通过在<grade>
标签中搜索CharData
标记并将其解析为浮点数来解析,当没有要解析的值时,将等级设置为0.0
。
英文:
To add to OneOfOne's solutions, you can also define your own UnmarshalXML
method.
Example (On play):
type Grade float64
func (g *Grade) UnmarshalXML(d *xml.Decoder, s xml.StartElement) error {
for tok, err := d.Token(); err != io.EOF; tok, err = d.Token() {
if chrdata, ok := tok.(xml.CharData); ok {
f, err := strconv.ParseFloat(string(chrdata), 64)
if err != nil {
return err
}
*(*float64)(g) = f
}
}
return nil
}
type Result struct {
XMLName xml.Name `xml:"Person"`
Grade Grade `xml:"grade"`
Name string `xml:"name"`
}
This parses the <grade>
tag by searching for CharData
tokens in between and parsing them as float, leaving the grade at 0.0
when there is no value to be parsed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论