Преобразование интерфейса{} в int
Я пытаюсь получить значение из 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
8 ответов:
вместо
iAreaId := int(val)вы хотите утверждение типа:
iAreaId := val.(int) iAreaId, ok := val.(int) // Alt. non panicking versionпричина, почему вы не можете преобразование типизированное значение интерфейса - это следующие правила в ссылочных спецификациях:
преобразования выражений вида
T(x)здесьTтип иx- это выражение, которое может быть преобразовано в значение типа T....
непостоянное значение x может быть преобразован в тип T в любом из этих случаев:
- x присваивается T.
- тип x и T имеют идентичные базовые типы.
- типы x и T являются неназванными типами указателей, а их базовые типы указателей имеют идентичные базовые типы.
- тип x и T являются целочисленными или с плавающей запятой.
- тип x и T являются сложными типами.
- x-целое число или фрагмент байтов или рун, а T - строковый тип.
- x-строка, а T-фрагмент байтов или рун.
но
iAreaId := int(val)и не любой из случаев 1.-7.
Я предполагаю: если вы отправили значение JSON через браузер, то любое число, которое вы отправили, будет типом float64, поэтому вы не можете получить значение непосредственно int в golang.
Так что преобразование, как:
//Как говорится: fmt.Fprintf (w, "Type = %v", val) / /
var iAreaId int = int (val.(float64))
таким образом, вы можете получить точное значение, что вы хотели.
я полностью согласен с zzzz ' s утверждение типа ответ, и я сильно предпочитаю этот путь над другими. Тем не менее, вот что мне пришлось сделать, когда предпочтительный метод не сработал... (длинная история, связанная с перекрестной сериализацией данных). Вы даже можете связать это в
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 */ } }как я уже сказал выше, попробуйте утверждение типа сначала, прежде чем попробовать этот путь.
Я написал библиотеку, которая может помочь с преобразованиями типов 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)дополнительная информация скачать.
чтобы лучше понять преобразование типа, посмотрите на код ниже:
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
для выражения x типа интерфейса и типа T, первичное выражение x.(T) утверждает, что x не является нулем и что значение, хранящееся в x, имеет тип T. обозначение x. (T) называется утверждением типа. Точнее, если T не является типом интерфейса, x. (T) утверждает, что динамический тип x является идентичный типу T. В этом случае T должен реализовать (интерфейсный) тип x; в противном случае утверждение типа недопустимо, поскольку x не может хранить значение типа T. Если T является типом интерфейса, x.(T) утверждает, что динамический тип x реализует интерфейс T.
возвращаясь к вашему коду, это
iAreaId := val.(int)должны хорошо работать. Если вы хотите проверить ошибку, возникшую во время преобразования, вы также можете переписать выше строки как
iAreaId, ok := val.(int)
Comments