dongtiannan0367 2019-01-30 07:37
浏览 17
已采纳

如何使函数接受字符串参数,并根据它返回不同的结构类型?

I want to create a function that takes string argument, and depending of string returns different types

In my current project I am using Go version 1.11.4 for Rest API, PostgreSQL 11 for storing data. The function is for avoiding the code redundancy, I just need one function for handling the requests, whithout this function I would be write more many request handlers.

Functions is:

func GetArrayOfModelStructs(table_name string) interface{} {
    if table_name == "prefs_n_cities" {
        Prefs_n_cities_array := &models.Prefs_n_cities_array{}
        return Prefs_n_cities_array
    } else if table_name == "position_owner" {
        Position_owners := &models.Position_owners{}
        return Position_owners
    } else if table_name == "region" {
        Regions := &models.Regions{}
        return Regions
    } else if table_name == "district" {
        Districts := &models.Districts{}
        return Districts
    } else if table_name == "locality" {
        Localities := &models.Localities{}
        return Localities
    } else if table_name == "locality_type" {
        Locality_types := &models.Locality_types{}
        return Locality_types
    } else if table_name == "population" {
        Populations := &models.Populations{}
        return Populations
    }
    return nil
}
func GetModelStructs(table_name string) interface{} {
    if table_name == "prefs_n_cities" {
        return models.Prefs_n_cities{}
    } else if table_name == "position_owner" {
        return models.Position_owner{}
    } else if table_name == "region" {
        return models.Regions{}
    } else if table_name == "district" {
        return models.District{}
    } else if table_name == "locality" {
        return models.Locality{}
    } else if table_name == "locality_type" {
        return models.Locality_type{}
    } else if table_name == "population" {
        return models.Population{}
    }
    return nil
}

My structs example like:

type Prefs_n_cities struct {
    id          int32
    Name        string
    Description string
    Region_id   int32
}

type Prefs_n_cities_array struct {
    Array []Prefs_n_cities
}

And all of this I trying to use in another package for handling requests:

var GetData = func(res http.ResponseWriter, req *http.Request) {
    // u.Logging(req, false)
    db_name := req.URL.Query().Get("table_name")

    data := u.GetArrayOfModelStructs(db_name)

    spew.Dump(data)

    sqlString := `SELECT * FROM "new_rollout_managment".` + db_name

    rows, err := database.DB.Query(sqlString)
    if err != nil {
        http.Error(res, err.Error(), 400)
        return
    }
    defer rows.Close()

    for rows.Next() {
        model := u.GetModelStructs(db_name)
        err = rows.Scan(&model)
        if err != nil {
            http.Error(res, err.Error(), 400)
            return
        }
        data.Array = append(data.Array, model)
    }
    err = rows.Err()
    if err != nil {
        http.Error(res, err.Error(), 400)
        return
    }

    out, err := json.Marshal(models)
    if err != nil {
        http.Error(res, err.Error(), 500)
        return
    }

    resp := u.Message(true, "Array of dictionaries")
    resp["Dictionaries"] = out

    u.Respond(res, resp)
}

My router is:

func Use(router *mux.Router) {

    router.HandleFunc("/api/test/new", controllers.TestFunc).Methods("POST")
    router.HandleFunc("/api/dictionaries/getdata", controllers.GetData).Methods("GET")
}

But in the GetData handler I have an error:

data.Array undefined (type interface {} is interface with no methods)
  • 写回答

1条回答 默认 最新

  • dongquxiao8545 2019-01-30 07:44
    关注

    You can't do that. But you have two options:

    1. Return an interface{}, as you are doing, then convert to a concrete type. This probably defeats your purpose.

    2. Pass in your destination as a pointer, and modify it in place. So something like:

      func GetArrayOfModelStructs(table_name string, dst interface{}) error {
      

      Then have your function put the value in dst. This does require that the value passed as dst is a pointer. This is a very common pattern, seen in json.Unmarshal(), in sql's Rows.Scan, and many other places in the standard library and elsewhere.

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

报告相同问题?

悬赏问题

  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等
  • ¥15 matlab 用yalmip搭建模型,cplex求解,线性化处理的方法
  • ¥15 qt6.6.3 基于百度云的语音识别 不会改
  • ¥15 关于#目标检测#的问题:大概就是类似后台自动检测某下架商品的库存,在他监测到该商品上架并且可以购买的瞬间点击立即购买下单
  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来