Nice programing

interface {}를 int로 변환

nicepro 2020. 10. 4. 13:25
반응형

interface {}를 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

대신에

iAreaId := int(val)

유형 어설 션 을 원합니다 .

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

인터페이스 유형 값을 변환 할 수없는 이유 는 참조 된 스펙 파트의 다음 규칙 때문입니다.

전환은 형태의 표현식 타입이고 T. 유형으로 변환 될 수있는 표현이며T(x)Tx

...

다음과 같은 경우 상수가 아닌 값 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 유형이므로 golang에서 직접 값을 가져올 수 없습니다.

따라서 다음과 같이 변환하십시오.

//As that says: 
fmt.Fprintf(w, "Type = %v", val) // <--- Type = float64

var iAreaId int = int(val.(float64))

이렇게하면 원하는 정확한 가치를 얻을 수 있습니다.


나는 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 */
    }
}

위에서 말했듯 이 이런 식으로 시도하기 전에 먼저 유형 어설 션 을 시도하십시오.


사용하는 다른 답변 추가 switch... 더 포괄적 인 예가 있지만 아이디어를 얻을 수 있습니다.

예를 들어, tcase범위 내에서 지정된 데이터 유형이됩니다 . 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)
}

I wrote a library that can help with type convertions 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]

Simplest way I did this. Not the best way but simplest way I know how.

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
}

You need to do type assertion for converting your interface{} to int value.

iAreaId := val.(int)
iAreaId, ok := val.(int)

More information is available.


To better understand the type conversion, look at the code below:

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)
}

This code executes perfectly and converts interface type to int type

For an expression x of interface type and a type T, the primary expression x.(T) asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion. More precisely, if T is not an interface type, x.(T) asserts that the dynamic type of x is identical to the type T. In this case, T must implement the (interface) type of x; otherwise the type assertion is invalid since it is not possible for x to store a value of type T. If T is an interface type, x.(T) asserts that the dynamic type of x implements the interface T.

Going back to your code, this

iAreaId := val.(int)

should work good. If you want to check error occured while conversion, you can also re-write above line as

iAreaId, ok := val.(int)


Best avoid casting by declaring f to be f the correct type to correspond to the JSON.

참고URL : https://stackoverflow.com/questions/18041334/convert-interface-to-int

반응형