Я пытаюсь получить значение из JSON и преобразовать его в int, но это не работает, и я не знаю, как это сделать правильно.
Вот сообщение об ошибке:
...cannot convert val (type interface {}) to type int: need type assertion
И код:
var f interface{}
err = json.Unmarshal([]byte(jsonStr), &f)
if err != nil {
utility.CreateErrorResponse(w, "Error: failed to parse JSON data.")
return
}
m := f.(map[string]interface{})
val, ok := m["area_id"]
if !ok {
utility.CreateErrorResponse(w, "Error: Area ID is missing from submitted data.")
return
}
fmt.Fprintf(w, "Type = %v", val) // <--- Type = float64
iAreaId := int(val) // <--- Error on this line.
testName := "Area_" + iAreaId // not reaching here
Я предполагаю: если вы отправили значение JSON через браузер, то любое отправленное вами число будет иметь тип float64, поэтому вы не сможете получить значение напрямую int в golang.
Так что сделайте преобразование, например:
//As that says: fmt.Fprintf(w, "Type = %v", val) // <--- Type = float64 var iAreaId int = int(val.(float64))
Таким образом вы сможете получить именно то, что вам нужно.
источник
Добавление еще одного ответа, который использует
switch
... Есть более подробные примеры, но это даст вам представление.Например,
t
становится указанным типом данных в каждойcase
области. Обратите внимание, что вы должны предоставитьcase
только один тип в типе, в противном случаеt
остаетсяinterface
.package main import "fmt" func main() { var val interface{} // your starting value val = 4 var i int // your final value switch t := val.(type) { case int: fmt.Printf("%d == %T\n", t, t) i = t case int8: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case int16: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case int32: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case int64: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case bool: fmt.Printf("%t == %T\n", t, t) // // not covertible unless... // if t { // i = 1 // } else { // i = 0 // } case float32: fmt.Printf("%g == %T\n", t, t) i = int(t) // standardizes across systems case float64: fmt.Printf("%f == %T\n", t, t) i = int(t) // standardizes across systems case uint8: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case uint16: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case uint32: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case uint64: fmt.Printf("%d == %T\n", t, t) i = int(t) // standardizes across systems case string: fmt.Printf("%s == %T\n", t, t) // gets a little messy... default: // what is it then? fmt.Printf("%v == %T\n", t, t) } fmt.Printf("i == %d\n", i) }
источник
case string
вы можете использовать,strconv.ParseFloat(t, 32)
а затемint
Я всем сердцем согласен с ZZZZ «ы утверждение типа ответа , и я сильно предпочитаю , что путь над другими. Тем не менее, вот что мне пришлось сделать, когда предпочтительный метод не сработал ... (долгая история, связанная с кросс-сериализацией данных). Вы даже можете связать это с
switch
операторомcase errInt == nil
и похожими выражениями.package main import "fmt" import "strconv" func main() { var v interface{} v = "4" i, errInt := strconv.ParseInt(v.(string), 10, 64) if errInt == nil { fmt.Printf("%d is a int", i) /* do what you wish with "i" here */ } }
Как я сказал выше, сначала попробуйте ввести assertion, прежде чем пытаться сделать это.
источник
strconv.ParseFloat(v.(string), 64)
вместо этого. Скажем, вы также можете изменить имена переменныхerrFloat
.Чтобы лучше понять преобразование типов, посмотрите на приведенный ниже код:
package main import "fmt" func foo(a interface{}) { fmt.Println(a.(int)) // conversion of interface into int } func main() { var a int = 10 foo(a) }
Этот код отлично работает и преобразует тип интерфейса в тип int.
Возвращаясь к вашему коду, это
iAreaId := val.(int)
должно работать хорошо. Если вы хотите проверить, что при преобразовании произошла ошибка, вы также можете переписать строку выше как
iAreaId, ok := val.(int)
источник
Я написал библиотеку, которая может помочь с преобразованием типов https://github.com/KromDaniel/jonson
js := jonson.New([]interface{}{55.6, 70.8, 10.4, 1, "48", "-90"}) js.SliceMap(func(jsn *jonson.JSON, index int) *jonson.JSON { jsn.MutateToInt() return jsn }).SliceMap(func(jsn *jonson.JSON, index int) *jonson.JSON { if jsn.GetUnsafeInt() > 50{ jsn.MutateToString() } return jsn }) // ["55","70",10,1,48,-90]
источник
Самый простой способ, которым я это сделал. Не лучший способ, но самый простой способ, который я знаю.
import "fmt" func main() { fmt.Print(addTwoNumbers(5, 6)) } func addTwoNumbers(val1 interface{}, val2 interface{}) int { op1, _ := val1.(int) op2, _ := val2.(int) return op1 + op2 }
источник
Вам нужно сделать утверждение типа для преобразования вашего интерфейса {} в значение типа int.
iAreaId := val.(int) iAreaId, ok := val.(int)
Доступна дополнительная информация .
источник
может тебе нужно
func TransToString(data interface{}) (res string) { switch v := data.(type) { case float64: res = strconv.FormatFloat(data.(float64), 'f', 6, 64) case float32: res = strconv.FormatFloat(float64(data.(float32)), 'f', 6, 32) case int: res = strconv.FormatInt(int64(data.(int)), 10) case int64: res = strconv.FormatInt(data.(int64), 10) case uint: res = strconv.FormatUint(uint64(data.(uint)), 10) case uint64: res = strconv.FormatUint(data.(uint64), 10) case uint32: res = strconv.FormatUint(uint64(data.(uint32)), 10) case json.Number: res = data.(json.Number).String() case string: res = data.(string) case []byte: res = string(v) default: res = "" } return }
источник
Лучше избегать приведения типов, объявляя f как f - правильный тип, соответствующий JSON.
источник