Карта для хранения функций универсального типа в Go - PullRequest
0 голосов
/ 12 сентября 2018

Я пытаюсь создать карту со строкой и функциями в качестве ключа и значения. Это работает, если все функции имеют одну и ту же сигнатуру, но мое требование - хранить функции с другой сигнатурой на одной карте. Возможно ли это в Go?

package main

import "fmt"

func main() {

    functions := buildFunctions()
    f := functions["isInValid"]

    //  f("hello")

}

func buildFunctions() map[string]func() bool {

    functions := map[string]func() bool{
        "isInValid":   isInValid,
        "isAvailable": isAvailable,
    }
    return functions
}

func isInValid(s string) bool {
    fmt.Println("Invalid ", s)
    return true
}

func isAvailable(s string, s1 string) bool {
    return true
}

https://play.golang.org/p/ocwCgEpa_0G

1 Ответ

0 голосов
/ 12 сентября 2018

Go - строго типизированный язык.Таким образом, это не возможно так, как, скажем, с python.Но, как и в случае с python, вы теряете преимущество проверки ошибок во время компиляции, и ваша проверка ошибок во время выполнения должна быть полной.Вот что вы можете сделать:

  1. Используйте map[string]interface{} тип для вашей карты функций , которая позволяет вам хранить что угодно.Но тогда вы несете ответственность за правильность ввода утверждения во время вызова.Проблема заключается в том, что в большинстве случаев, если при вызове функции вы могли знать тип функции, возможно, вам может не понадобиться карта в первую очередь.

  2. Используйте map[string]string или map[string]interface{} в качестве аргумента и возвращайте тип во всех функциях, которые должны входить в эту карту.Или, по крайней мере, поместите все переменные аргументы в эту карту.

    например.

    map[string](func (name string, age int, other_attributes map[string]interface{}) (map[string]interface{}, error))

Но, опять же, каждый вызов функции должен обеспечиватьправильные аргументы, и внутри функций также должны быть проверки, чтобы видеть (с не панической версией просмотра карты), если параметры предоставлены правильно, если нет, вы можете возвратить пользовательскую ошибку, такую ​​как ErrInvalidParametersPassed.(играет роль переводчика).Но у вас все равно будет меньше шансов испортить, по сравнению с первым вариантом.Так как burden of type assertion будет на реализации функции, а не на вызывающей стороне.Вызывающему абоненту просто нужно получить требуемые значения, о которых он в любом случае должен знать.

Но, тем не менее, наилучшим вариантом было бы перестроить ваше реальное решение таким образом, чтобы это можно было сделать без движения по этому пути.Как подсказывает @bereal в комментариях, хорошо иметь отдельные карты, если это возможно, или, возможно, использовать расширенный набор аргументов, если они не слишком разные или слишком много.Если есть только несколько аргументов, даже случай переключения может быть достаточно чистым.Ищите способы проверки времени обхода / обхода, если вы действительно уверены, что другого элегантного способа не существует.

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