为了账号安全,请及时绑定邮箱和手机立即绑定

如何减少 Golang 中重复函数的冗余代码?

如何减少 Golang 中重复函数的冗余代码?

Go
MYYA 2022-05-10 16:12:52
我有一个 Rest API 应用程序可以将所有 json 数据列出到浏览器。只要我有更多模块,我的代码就会更加冗余。和复杂。func UserList(w http.ResponseWriter, r *http.Request) {    list := []models.User{}    db.Find(&list)    json.NewEncoder(w).Encode(list)}func ProductList(w http.ResponseWriter, r *http.Request) {    list := []models.Product{}    db.Find(&list)    json.NewEncoder(w).Encode(list)}func OrderList(w http.ResponseWriter, r *http.Request) {    list := []models.Order{}    db.Find(&list)    json.NewEncoder(w).Encode(list)}有没有更好的解决方案可以将这段代码变成一个函数示例func List(w http.ResponseWriter, r *http.Request) {    list := ??? List of struct here ???    db.Find(&list)    json.NewEncoder(w).Encode(list)}
查看完整描述

3 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

你可以这样做:


func List(list interface{}, w http.ResponseWriter, r *http.Request,) {

    db.Find(list)

    json.NewEncoder(w).Encode(list)

}


查看完整回答
反对 回复 2022-05-10
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

鉴于您正在调用,db.Find(&list)我假设它们共享一个通用接口。在这种情况下,您可以像这样包装您的处理程序调用;


func ListHandler(list <YOUR_INTERFACE>) func(w http.ResponseWriter, r *http.Request) {

    return func(w http.ResponseWriter, r *http.Request) {

        db.Find(&list)

        json.NewEncoder(w).Encode(list)

    }

}

在您的电话中;


http.HandleFunc("/user/list", ListHandler([]models.User{}))

http.HandleFunc("/product/list", ListHandler([]models.Product{}))

http.HandleFunc("/order/list", ListHandler([]models.Order{}))


查看完整回答
反对 回复 2022-05-10
?
呼如林

TA贡献1798条经验 获得超3个赞

如果您将模型类型作为请求参数传递,则应该这样做(包括错误处理):


func List(w http.ResponseWriter, r *http.Request) {

    var list interface{}

    switch r.FormValue("model") {

    case "user":

        list = new([]models.User)

    case "product":

        list = new([]models.Product)

    case "order":

        list = new([]models.Order)

    default:

        http.Error(w, "invalid type", http.StatusBadRequest)

        return

    }

    if err := db.Find(list); err != nil {

        http.Error(w, "db error", http.StatusInternalServerError)

        return

    }

    if err := json.NewEncoder(w).Encode(list); err != nil {

        log.Printf("json encoding error: %v", err)

    }

}

另一种选择是建立一个类型的注册表,甚至切片的创建可以被分解,使用帮助reflect:


var reg = map[string]reflect.Type{

    "user":    reflect.TypeOf((*models.User)(nil)).Elem(),

    "product": reflect.TypeOf((*models.Product)(nil)).Elem(),

    "order":   reflect.TypeOf((*models.Order)(nil)).Elem(),

}


func List(w http.ResponseWriter, r *http.Request) {

    etype := reg[r.FormValue("model")]

    if etype == nil {

        http.Error(w, "invalid type", http.StatusBadRequest)

        return

    }


    list := reflect.New(reflect.SliceOf(etype)).Interface()

    if err := db.Find(list); err != nil {

        http.Error(w, "db error", http.StatusInternalServerError)

        return

    }

    if err := json.NewEncoder(w).Encode(list); err != nil {

        log.Printf("json encoding error: %v", err)

    }

}


查看完整回答
反对 回复 2022-05-10
  • 3 回答
  • 0 关注
  • 216 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信