Преобразование интерфейса{} в 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
628   8  
go

8 ответов:

вместо

iAreaId := int(val)

вы хотите утверждение типа:

iAreaId := val.(int)
iAreaId, ok := val.(int) // Alt. non panicking version 

причина, почему вы не можете преобразование типизированное значение интерфейса - это следующие правила в ссылочных спецификациях:

преобразования выражений вида T(x) здесь T тип и x - это выражение, которое может быть преобразовано в значение типа T.

...

непостоянное значение x может быть преобразован в тип T в любом из этих случаев:

  1. x присваивается T.
  2. тип x и T имеют идентичные базовые типы.
  3. типы x и T являются неназванными типами указателей, а их базовые типы указателей имеют идентичные базовые типы.
  4. тип x и T являются целочисленными или с плавающей запятой.
  5. тип x и T являются сложными типами.
  6. x-целое число или фрагмент байтов или рун, а T - строковый тип.
  7. 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)

лучше всего избегать приведения, объявив f правильным типом, соответствующим JSON.

Comments

    Ничего не найдено.