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)
T
x
…
다음과 같은 경우 상수가 아닌 값 x를 T 유형으로 변환 할 수 있습니다.
- x는 T에 할당 할 수 있습니다.
- x의 유형과 T는 동일한 기본 유형을 갖습니다.
- x의 유형과 T는 명명되지 않은 포인터 유형이며 포인터 기본 유형은 동일한 기본 유형을 갖습니다.
- x의 유형과 T는 모두 정수 또는 부동 소수점 유형입니다.
- x의 유형과 T는 모두 복합 유형입니다.
- x는 정수 또는 바이트 또는 룬 조각이고 T는 문자열 유형입니다.
- 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))
이렇게하면 원하는 정확한 가치를 얻을 수 있습니다.
답변
사용하는 또 다른 답변 추가 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)
}
답변
나는 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 */
}
}
위에서 말했듯 이 이런 식으로 시도하기 전에 먼저 유형 어설 션 을 시도하십시오.
답변
유형 변환을 더 잘 이해하려면 아래 코드를보십시오.
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가 nil이 아니며 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)
답변
유형 변환에 도움이되는 라이브러리를 작성했습니다.
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
}