Как сделать функцию, которая принимает строковый аргумент и в зависимости от этого возвращает разные типы структур? - PullRequest
0 голосов
/ 30 января 2019

Я хочу создать функцию, которая принимает строковый аргумент, и в зависимости от строки возвращает разные типы

В моем текущем проекте я использую Go версию 1.11.4 для Rest API, PostgreSQL 11 для хранения данных.Функция предназначена для избежания избыточности кода, мне просто нужна одна функция для обработки запросов, без этой функции я бы написал больше обработчиков запросов.

Функции:

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
}

Мой пример структур:

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

type Prefs_n_cities_array struct {
    Array []Prefs_n_cities
}

И все это я пытаюсь использовать в другом пакете для обработки запросов:

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

Мой маршрутизатор:

func Use(router *mux.Router) {

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

Но в обработчике GetData у меня ошибка:

data.Array undefined (type interface {} is interface with no methods)

1 Ответ

0 голосов
/ 30 января 2019

Вы не можете этого сделать.Но у вас есть два варианта:

  1. Возврат interface{}, как вы делаете, а затем преобразовать в конкретный тип.Это, вероятно, побеждает вашу цель.

  2. Передайте пункт назначения в качестве указателя и измените его на месте.Так что-то вроде:

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

    Затем ваша функция поместит значение в dst.Это требует, чтобы значение, переданное как dst, было указателем.Это очень распространенная модель, встречающаяся в json.Unmarshal(), в sql Rows.Scan и во многих других местах стандартной библиотеки и в других местах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...