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.

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

报告相同问题?

悬赏问题

  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换