Как передать структуру данных как параметр в 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("%sn", per)

    var places Places
    xml.Unmarshal([]byte(placeXml), &places)
    pla, _ := json.Marshal(places)
    fmt.Printf("%sn", pla)

    var parks Parks
    xml.Unmarshal([]byte(parkXml), &parks)
    par, _ := json.Marshal(parks)
    fmt.Printf("%sn", par)
}

что я хочу, это общая функция, которая принимает строку xml и dataStruct и возвращает вывод Json. Но ниже функция бросает ошибку Как это сделать?

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("%sn", js), nil
}

func main() {
    jsonstring, _ := Xml2Json(personXml, Persons)
}

сообщение об ошибке:

prog.go: 73: DataStruct не является типом

prog.go: 80: Тип Persons не является выражением

ссылка goplay:http://play.golang.org/p/vayb0bawKx

2 ответов


вы не можете хранить типа (например,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)

когда вы хотите получить значение структуры для последующей обработки.


функции Xml2Json объявляет параметр с именем DataStruct. В той же области идентификатор DataStruct не может обозначать имя типа. Если вы хотите использовать имя типа DataStruct в той же области вы должны назвать свой параметр по-разному.

в основной функции проблема заключается в том, что синтаксис вызова функции ожидает список выражений в скобках. Вот вы проезжаете мимо имя типа, что явно не может быть выражением.

так ответить ваш вопрос: нет,вы не можете передать тип в качестве аргумента функции. Но ты! .. --9-->can передайте экземпляр типа (в данном случае указатель на такой экземпляр), чтобы получить эффект, о котором вы говорите:

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]}}