#json #go
# #json #Вперед
Вопрос:
Я хочу декодировать запрос JSON, чтобы значением поля могла быть одна строка или массив (список).
Я знаю, как анализировать if отдельно. но я ищу способ иметь динамический декодер для анализа их обоих.
value
Поле в JSON — это тот случай, о котором я говорю
Пример для однозначного:
{
"filter":{
"op":"IN",
"field":"name",
"value": "testDuplicate"
}
}
Пример для многозначного:
{
"filter":{
"op":"IN",
"field":"name",
"value":["testDuplicate","tt"]
}
}
Структуры для одного значения:
type DocumentTypeSearchRequest struct {
Filter DocTypeFilter `json:"filter"`
}
type DocTypeFilter struct {
Op string `json:"op"`
Field string `json:"field"`
Value string `json:"value"`
}
Структуры для многозначных:
type DocumentTypeSearchRequest struct {
Filter DocTypeFilter `json:"filter"`
}
type DocTypeFilter struct {
Op string `json:"op"`
Field string `json:"field"`
Value []string `json:"value"`
}
Одно из решений — попытаться декодировать с помощью одного из них, если не удалось использовать другой, но я не уверен, что это правильный способ решения этой проблемы.
Комментарии:
1. @Jamiec один из них — строка Value [], а другой —
json:"value"
строка Valuejson:"value"
имеет ли это смысл?2. @super пожалуйста, взгляните на мой комментарий. из них это фрагмент строки, а другой — просто строка
3. Нет, потому что ваш ввод json всегда содержит массив значений в json (должно ли одно из них иметь только одно значение? если нет, что вы собираетесь делать с остальными?)
4. @
value
Jamiec здесь дело в поле. это какой-то запрос, это всего лишь строка. в некоторых запросах это список строк.
Ответ №1:
Вам нужен пользовательский разделитель. Я говорил о подобной ситуации в этом видео:
type Value []string
func (v *Value) UnmarshalJSON(p []byte) error {
if p[0] == '[' { // First char is '[', so it's a JSON array
s := make([]string, 0)
err := json.Unmarshal(p, amp;s)
*v = Value(s)
return err
}
// else it's a simple string
*v = make(Value, 1)
return json.Unmarshal(p, amp;(*v)[0])
}
С этим определением Value
ваша структура станет чем-то вроде:
type DocTypeFilter struct {
Op string `json:"op"`
Field string `json:"field"`
Value Value `json:"value"`
}
и теперь ваше Value
поле всегда будет срезом, но оно может содержать только одно значение, когда ваш ввод JSON представляет собой строку, а не массив.
Комментарии:
1.Я не уверен, что это работает так, как вы думали (или, скорее всего, будучи новичком в Go, я не могу настроить ваше решение, которое я просто использую в качестве учебного материала!)
cannot unmarshal string into Go struct field DocTypeFilter.filter.value of type []main.Value
ссылка на игровую площадку2. Не используйте
[]Value
, используйтеValue
.Value
сам по себе теперь является срезом, как[]Value
и срез срезов (не то, что вы хотите).3. @Flimzy спасибо за решение. Я попробовал это с моим случаем `{«filter»:{«op»:»EQ»,»field»:»name»,»value»:»testDuplicate»}, «page»:0,»page_size»:0} json, но он возвращает ошибку. не могли бы вы, пожалуйста, обновить игровую площадку с образцом тоже? большое спасибо.
4. Вы имеете в виду вот так? play.golang.org/p/H_CcSaG-rmz
5. @Flimzy я имел в виду решение, которое анализирует образец json в вопросе. это «{«filter»:{«op»:»EQ»,»field»:»name»,»value»:»testDuplicate»},»page»:0,»page_size»: 0}». полный json