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 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格