英文:
How to pass data struct as parameter in golang
问题
XML转JSON
package main
import (
"encoding/json"
"encoding/xml"
"fmt"
)
type Persons struct {
Person []struct {
Name string
Age int
}
}
type Places struct {
Place []struct {
Name string
Country string
}
}
type Parks struct {
Park struct {
Name []string
Capacity []int
}
}
const personXml = `
<Persons>
<Person><Name>Koti</Name><Age>30</Age></Person>
<Person><Name>Kanna</Name><Age>29</Age></Person>
</Persons>
`
const placeXml = `
<Places>
<Place><Name>Chennai</Name><Country>India</Country></Place>
<Place><Name>London</Name><Country>UK</Country></Place>
</Places>
`
const parkXml = `
<Parks>
<Park><Name>National Park</Name><Capacity>10000</Capacity></Park>
<Park>Asian Park</Name><Capacity>20000</Capacity></Park>
</Parks>
`
func WhatIamUsing() {
var persons Persons
xml.Unmarshal([]byte(personXml), &persons)
per, _ := json.Marshal(persons)
fmt.Printf("%s\n", per)
var places Places
xml.Unmarshal([]byte(placeXml), &places)
pla, _ := json.Marshal(places)
fmt.Printf("%s\n", pla)
var parks Parks
xml.Unmarshal([]byte(parkXml), &parks)
par, _ := json.Marshal(parks)
fmt.Printf("%s\n", par)
}
func Xml2Json(xmlString string, dataStruct interface{}) (jsobj string, err error) {
xml.Unmarshal([]byte(xmlString), &dataStruct)
js, _ := json.Marshal(dataStruct)
return fmt.Sprintf("%s\n", js), nil
}
func main() {
jsonstring, _ := Xml2Json(personXml, Persons{})
fmt.Println(jsonstring)
}
错误信息:
prog.go:73: DataStruct不是一个类型
prog.go:80: 类型Persons不是一个表达式
goplay链接:http://play.golang.org/p/vayb0bawKx
英文:
XML to Json
package main
import (
"encoding/json"
"encoding/xml"
"fmt"
)
type Persons struct {
Person []struct {
Name string
Age int
}
}
type Places struct {
Place []struct {
Name string
Country string
}
}
type Parks struct {
Park struct {
Name []string
Capacity []int
}
}
const personXml = `
<Persons>
<Person><Name>Koti</Name><Age>30</Age></Person>
<Person><Name>Kanna</Name><Age>29</Age></Person>
</Persons>
`
const placeXml = `
<Places>
<Place><Name>Chennai</Name><Country>India</Country></Place>
<Place><Name>London</Name><Country>UK</Country></Place>
</Places>
`
const parkXml = `
<Parks>
<Park><Name>National Park</Name><Capacity>10000</Capacity></Park>
<Park>Asian Park</Name><Capacity>20000</Capacity></Park>
</Parks>
`
func WhatIamUsing() {
var persons Persons
xml.Unmarshal([]byte(personXml), &persons)
per, _ := json.Marshal(persons)
fmt.Printf("%s\n", per)
var places Places
xml.Unmarshal([]byte(placeXml), &places)
pla, _ := json.Marshal(places)
fmt.Printf("%s\n", pla)
var parks Parks
xml.Unmarshal([]byte(parkXml), &parks)
par, _ := json.Marshal(parks)
fmt.Printf("%s\n", par)
}
What i want is a generic function which takes xml string and dataStruct
and returns a Json output. But below function is throwing an error
How to impliment this?
func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) {
var dataStruct DataStruct
xml.Unmarshal([]byte(personXml), &dataStruct)
js, _ := json.Marshal(dataStruct)
return fmt.Sprintf("%s\n", js), nil
}
func main() {
jsonstring, _ := Xml2Json(personXml, Persons)
}
Error message:
prog.go:73: DataStruct is not a type
prog.go:80: type Persons is not an expression
goplay link: http://play.golang.org/p/vayb0bawKx
答案1
得分: 13
你不能将一个类型(比如Persons
)存储在一个接口中。你可以将reflect.Type
传递给你的函数。然后,你的调用会像这样:Xml2Json(personXml, reflect.TypeOf(Persons))
,我认为这样写很丑陋。
更好的方法可能是:
func Xml2Json(xmlString string, value interface{}) (string, error) {
if err := xml.Unmarshal([]byte(xmlString), value); err != nil {
return "", err
}
js, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(js), nil
}
如果你只对值本身不感兴趣,你可以使用Xml2Json(personXml, new(Persons))
来调用这个函数,如果你还想获取结构体值以供以后处理,你可以使用:
var persons Persons
Xml2Json(personXML, &persons)
英文:
You can not store a type (like Persons
) in an interface. You could pass a reflect.Type
to your function. Then, your call would look like Xml2Json(personXml, reflect.TypeOf(Persons))
which is quite ugly in my opinion.
The better approach is probably:
func Xml2Json(xmlString string, value interface{}) (string, error) {
if err := xml.Unmarshal([]byte(xmlString), value); err != nil {
return "", err
}
js, err := json.Marshal(value)
if err != nil {
return "", err
}
return string(js), nil
}
You can use this function with Xml2Json(personXml, new(Persons))
if you are not interested in the value itself, and
var persons Persons
Xml2Json(personXML, &persons)
when you also want to retrieve the struct value for later processing.
答案2
得分: 1
Xml2Json
函数声明了一个名为DataStruct
的参数。在同一作用域中,标识符DataStruct
不能表示类型名称。如果你想在同一作用域中使用类型名称DataStruct
,你必须给你的参数取一个不同的名字。
在main
函数中的问题是函数调用语法在括号内期望一个表达式列表。你在那里传递的是一个_类型名称_,显然不能是一个表达式。
所以回答你的问题:不,你不能将类型作为参数传递给函数。但是你可以传递一个类型的实例(在这种情况下是指向这种实例的指针),以获得你想要的效果:
package main
import (
"encoding/json"
"encoding/xml"
"fmt"
"log"
)
type Persons struct {
Person []struct {
Name string
Age int
}
}
type Places struct {
Place []struct {
Name string
Country string
}
}
type Parks struct {
Park struct {
Name []string
Capacity []int
}
}
const (
personXml = `
<Persons>
<Person><Name>Koti</Name><Age>30</Age></Person>
<Person><Name>Kanna</Name><Age>29</Age></Person>
</Persons>
`
placeXml = `
<Places>
<Place><Name>Chennai</Name><Country>India</Country></Place>
<Place><Name>London</Name><Country>UK</Country></Place>
</Places>
`
parkXml = `
<Parks>
<Park><Name>National Park</Name><Capacity>10000</Capacity></Park>
<Park><Name>Asian Park</Name><Capacity>20000</Capacity></Park>
</Parks>
`
)
func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) {
if err = xml.Unmarshal([]byte(xmlString), DataStruct); err != nil {
return
}
js, err := json.Marshal(DataStruct)
if err != nil {
return
}
return fmt.Sprintf("%s", js), nil
}
func main() {
var p Persons
jsonstring, err := Xml2Json(personXml, &p)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonstring)
var q Places
jsonstring, err = Xml2Json(placeXml, &q)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonstring)
var r Parks
jsonstring, err = Xml2Json(parkXml, &r)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonstring)
}
输出:
{"Person":[{"Name":"Koti","Age":30},{"Name":"Kanna","Age":29}]}
{"Place":[{"Name":"Chennai","Country":"India"},{"Name":"London","Country":"UK"}]}
{"Park":{"Name":["National Park","Asian Park"],"Capacity":[10000,20000]}}
英文:
The function Xml2Json
declares a parameter named DataStruct
. In the same scope the identifier DataStruct
cannot denote a type name. If you want to use the type name DataStruct
within the same scope, you must name your parameter differently.
In the main function the problem is that a function call syntax expects an expression list within the parenthesis. There you're passing a type name, which clearly cannot be an expression.
So to answer your question: No, you cannot pass a type as an argument to a function. But you can pass an instance of a type (in this case a pointer to such instance) to get the effect you're about:
package main
import (
"encoding/json"
"encoding/xml"
"fmt"
"log"
)
type Persons struct {
Person []struct {
Name string
Age int
}
}
type Places struct {
Place []struct {
Name string
Country string
}
}
type Parks struct {
Park struct {
Name []string
Capacity []int
}
}
const (
personXml = `
<Persons>
<Person><Name>Koti</Name><Age>30</Age></Person>
<Person><Name>Kanna</Name><Age>29</Age></Person>
</Persons>
`
placeXml = `
<Places>
<Place><Name>Chennai</Name><Country>India</Country></Place>
<Place><Name>London</Name><Country>UK</Country></Place>
</Places>
`
parkXml = `
<Parks>
<Park><Name>National Park</Name><Capacity>10000</Capacity></Park>
<Park><Name>Asian Park</Name><Capacity>20000</Capacity></Park>
</Parks>
`
)
func Xml2Json(xmlString string, DataStruct interface{}) (jsobj string, err error) {
if err = xml.Unmarshal([]byte(xmlString), DataStruct); err != nil {
return
}
js, err := json.Marshal(DataStruct)
if err != nil {
return
}
return fmt.Sprintf("%s", js), nil
}
func main() {
var p Persons
jsonstring, err := Xml2Json(personXml, &p)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonstring)
var q Places
jsonstring, err = Xml2Json(placeXml, &q)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonstring)
var r Parks
jsonstring, err = Xml2Json(parkXml, &r)
if err != nil {
log.Fatal(err)
}
fmt.Println(jsonstring)
}
Output:
{"Person":[{"Name":"Koti","Age":30},{"Name":"Kanna","Age":29}]}
{"Place":[{"Name":"Chennai","Country":"India"},{"Name":"London","Country":"UK"}]}
{"Park":{"Name":["National Park","Asian Park"],"Capacity":[10000,20000]}}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论