2014-01-18 2 views
6

Я разрабатываю веб-сервис, который получит JSON. Go конвертирует типы слишком строгие.конвертировать интерфейс {} в определенный тип

Так что я следующая функция для преобразования interface{} в bool

func toBool(i1 interface{}) bool { 
    if i1 == nil { 
     return false 
    } 
    switch i2 := i1.(type) { 
    default: 
     return false 
    case bool: 
     return i2 
    case string: 
     return i2 == "true" 
    case int: 
     return i2 != 0 
    case *bool: 
     if i2 == nil { 
      return false 
     } 
     return *i2 
    case *string: 
     if i2 == nil { 
      return false 
     } 
     return *i2 == "true" 
    case *int: 
     if i2 == nil { 
      return false 
     } 
     return *i2 != 0 
    } 
    return false 
} 

Я считаю, что функция еще не совершена, и мне нужна функция для преобразования interface{} в string, int, int64 и т.д.

Так что мои вопрос: существует ли библиотека (набор функций) в Go, которая будет конвертировать interface{} в определенные типы

ОБНОВЛЕНИЕ

Мое веб-обслуживание принимаю JSON. Я декодирую его в map[string]interface{} У меня нет контроля над теми, кто его кодирует.

Таким образом, все значения, которые я получаю, равны interface{}, и мне нужен способ бросить его в определенных типах.

Так что может быть nil, int, float64, string, [...], {...} и я хочу, чтобы привести его к тому, что это должно быть. например int, float64, string, []string, map[string]string с обработкой всех возможных случаев, включая nil, неправильные значения, и т.д.

UPDATE2

Я получаю {"s": "wow", "x":123,"y":true}, {"s": 123, "x":"123","y":"true"}, {a:["a123", "a234"]}, {}

var m1 map[string]interface{} 
json.Unmarshal(b, &m1) 
s := toString(m1["s"]) 
x := toInt(m1["x"]) 
y := toBool(m1["y"]) 
arr := toStringArray(m1["a"]) 
+0

Не думаю, что есть один. – Agis

+0

Вы знаете, что пакет Go 'encoding/json' сделает все это для вас, не так ли? Но в любом случае библиотека 'reflect' может посмотреть интерфейс и рассказать вам, каковы реальные базовые ценности, если это то, что вы имеете в виду. –

+1

Почему? Можете ли вы рассказать мне больше о том, какие проблемы в реальном мире вы пытаетесь решить? - вы знаете https://gobyexample.com/json? – Matthias

ответ

6

objx package делает именно то, что вы хотите, он может работать напрямую с JSON, и даст вам значения по умолчанию и другие интересные функции:

Objx обеспечивает тип objx.Map, который является map[string]interface{} , который предоставляет мощный Get метод (среди других), что позволяет вам легко и быстро получить доступ к данным в карте, не имея слишком беспокоиться о утверждений типа, отсутствующих данных, значения по умолчанию и т.д.

Это небольшой пример использования:

o := objx.New(m1) 
s := o.Get("m1").Str() 
x := o.Get("x").Int() 
y := o.Get("y").Bool() 

arr := objx.New(m1["a"]) 

пример из дока работы с JSON:

// use MustFromJSON to make an objx.Map from some JSON 
m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) 

// get the details 
name := m.Get("name").Str() 
age := m.Get("age").Int() 

// get their nickname (or use their name if they 
// don't have one) 
nickname := m.Get("nickname").Str(name) 

Очевидно, что вы можете использовать что-то подобное с равнинным выполнением:

switch record[field].(type) { 
case int: 
    value = record[field].(int) 
case float64: 
    value = record[field].(float64) 
case string: 
    value = record[field].(string) 
} 

Но если проверить objx accessors вы можете увидеть сложный код аналогично этому, но со многими случаями использования, поэтому я считаю, что лучшим решением является использование библиотеки objx.

Смежные вопросы