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

问题描述 投票:0回答:3

我有一个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)
}
function go struct redundancy
3个回答
1
投票

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

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

0
投票

您可以执行以下操作:

func List(list interface{}, w http.ResponseWriter, r *http.Request,) {
    db.Find(list)
    json.NewEncoder(w).Encode(list)
}

0
投票

鉴于您正在调用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{}))
© www.soinside.com 2019 - 2024. All rights reserved.