dongyan1936 2015-02-04 19:38
浏览 73
已采纳

将`struct`作为类型名称传递给函数参数

I'm writing some sort of RESTfull API based Object relational mapper in go. I plan to make it MIT licensed, when i finish it. The idea is to use some 3rd party REST API as data storage, and the golang client will query it for data needed.

The API responses are JSONs with known structure.

this is my code:

type AClient struct {
    Id        string `json:"id"`
    Uid       string `json:"uid"`
    FirstName string `json:"firstName"`
    LastName  string `json:"lastName"`
    CreatedAt string `json:"createdAt"`
    UpdatedAt string `json:"updatedAt"`
    City      string `json:"city"`
    Address   string `json:"address"`
    Telefone  string `json:"telefone"`
    Zip       string `json:"zip"`
    Telefon   string `json:"telefon"`
    Comment   string `json:"comment"`
}

type AEvents struct {
    Id          string    `json:"id"`
    Security    bool      `json:"security"`
    Description string    `json:"description"`
    Good        AGood     `json:"good"`
    Client      AClient   `json:"client"`
    Author      AAuthor   `json:"author"`
    InFuture    bool      `json:"inFuture"`
    CreatedAt   time.Time `json:"createdAt"`
    UpdatedAt   time.Time `json:"updatedAt"`
}

type Entry struct {
    AEvents //this have to be changed to `AClients` in runtime when needed
}

type ORM struct {
    ApiUrl         string
    ModelName      string
    ModelInterface Entry
    HuntKey        string
    HuntSid        string
    Csrf           string
}

func (o *ORM) Query(parameters map[string]string) ([]Entry, AMetadata, error) {
    responseParsed := struct {
        Status   string    `json:"status"`
        Metadata AMetadata `json:"metadata"`
        Data     []Entry   `json:"data"` //todo - use o.ModelInterface
    }{}
    client := &http.Client{}

    var queryString string

    for k, v := range parameters {
        queryString = queryString + fmt.Sprintf("%v=%v&", url.QueryEscape(k), url.QueryEscape(v))
    }

    req, err := http.NewRequest("GET", fmt.Sprintf("%v%v?%v", o.ApiUrl, o.ModelName, queryString), nil)
    fmt.Println("---------------------------------------------")
    fmt.Println(fmt.Sprintf("[GET] %v%v?%v", o.ApiUrl, o.ModelName, queryString))
    req.Header.Set("huntKey", o.HuntKey)
    if err != nil {
        return nil, AMetadata{}, err
    }
    res, err1 := client.Do(req)
    defer res.Body.Close()
    if err1 != nil {
        return nil, AMetadata{}, err1
    }
    if res.StatusCode == 200 {
        for _, v := range res.Cookies() {
            if v.Name == "XSRF-TOKEN" {
                o.Csrf = v.Value
            }
            if v.Name == "hunt.sid" {
                o.HuntSid = v.Value
            }
        }
        fmt.Printf("CSRF %v
", o.Csrf)
        fmt.Printf("HuntSid %v
", o.HuntSid)
        fmt.Println("---------------------------------------------")
        raw, err2 := ioutil.ReadAll(res.Body)
        if err2 != nil {
            return nil, AMetadata{}, err2
        } else {
            err2 = json.Unmarshal(raw, &responseParsed)
            return responseParsed.Data, responseParsed.Metadata, nil
        }
    } else {
        return nil, AMetadata{}, errors.New("Unable to fetch data!")
    }
}

How can I make this: When instantiating the ORM object, how can i pass the struct name, that will be used to parse the JSON response. The current code works with the struct of AEvents, but i want it to be easy changeble t AClient and so on.

UPD: i have reviewed the code of https://github.com/jinzhu/gorm and find out tons of things how can i implement it. Than, as i have promised, I publish this code as open source -https://github.com/vodolaz095/hrorm

  • 写回答

1条回答 默认 最新

  • duanping6698 2015-02-04 20:05
    关注

    You can use reflection, but be warned that it is non-trivial and relatively slow. I don't know of any other way.

    The simplest way to do this is to make your parameter of type interface{} and pass in an empty (uninitialized) instance of the struct you wish to unmarshal into. I highly suggest reading the second of the two links I list - it provides a clear introduction to reflection and how to use it for solving problems like this one.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 STK matlab python仿真
  • ¥15 关于IMageEnView 图标定位问题
  • ¥20 求解答(matlab)
  • ¥30 ffmpeg库使用过程中遇到的问题
  • ¥15 pyqt5 中python如何通过Qtwebchannel主动发消息给web前端
  • ¥15 关于HTML中title获取xml内容的问题
  • ¥15 fanuc机器人PRIO083数字信号未复原错误,如何解决?
  • ¥20 如何为现有电路板增加远程控制功能
  • ¥15 UE5打包失败,求解决
  • ¥15 请问STM32G431的CANOPEN协议函数怎么写