@HellWalk

Как передать любой тип данных в фильтрации?

Сразу пару примечаний:
- у меня нет опыта работы в языках со статической типизацией
- вопрос не в том, как решить задачу, а в том, чтобы найти хорошее стандартное решение
- если есть какие-то хаки конкретно в go для таких задач - то они не особо интересны, потому что те же данные (структуру данных) нужно будет делать в gRPC.

Суть задачи: необходимо передать данные для фильтрации, с двумя параметрами: поле, по которому будет делаться фильтрация, и значение, по по которому будут отбираться данные из базы. Так как поле может быть любым, то и данные могут быть любого типа: string, int, bool и т.д.

Решение, которое пришло сходу, это передавать значение отдельным объектом (структурой), в котором будет указано, какого типа это значение:

{
    "type": "string",
    "value": {
        "string": "filter value",
        "int": 0,
        "bool": false
    }
}


А данные по фильтрации в целом будут выглядеть так:

{
    "filed": "field_name",
    "value": {
        "type": "int",
        "value": {
            "string": "",
            "int": 100,
            "bool": false
        }
    }
}


Ну и логика работы с таким форматом понятна - смотрим, какой тип данных, и получаем его значение из нужного поля.
  • Вопрос задан
  • 111 просмотров
Пригласить эксперта
Ответы на вопрос 1
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
В Go нельзя использовать строковое значение как квалификатор типа. То есть нельзя написать:
var Type string
Type = "int"
var foo Type // так не работает
var foo "int" // и так не работает

Из известных мне языков так нигде нельзя.
В конкретном вашем примере сниппеты похоже на JSON. В Go это парсится примерно так:
type Message struct {
		Type string
		Payload json.RawMessage // разобрать со второго захода
}
var message Message
// первый заход, Payload пока не парсится, остаётся json.RawMessage
json.Unmarshal(data, message)
// варианты типа
switch message.Type {
		case "string":
			dst = new(StringPayload) // готовим контейнер для типа string
		case "int":
			dst = new(IntPayload) // контейнер для int
}
// теперь разбираем Payload в подходящий контейнер
json.Unmarshal(message.Payload, dst)

gRPC обычно использует в качестве контейнера для сообщений protobuf. protobuf это строго типизированный язык. Передать на нём generic сообщение вообще вряд ли получится, по крайней мере не видел что бы кто нибудь делал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы