Go 将接口{}转换为int

Go 将接口{}转换为int,go,Go,我试图从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.CreateEr

我试图从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
var f接口{}
err=json.Unmarshal([]字节(jsonStr),&f)
如果出错!=零{
CreateErrorResponse(w,“错误:解析JSON数据失败”)
返回
}
m:=f.(映射[字符串]接口{})
val,ok:=m[“区域id”]
如果!嗯{
CreateErrorResponse(w,“错误:提交的数据中缺少区域ID”)
返回
}
fmt.Fprintf(w,“Type=%v”,val)/而不是

iAreaId := int(val)
你想要一个:

无法输入接口类型值的原因是引用的规范部分中的以下规则:

转换是
T(x)
形式的表达式,其中
T
是一种类型,
x
是一种可以转换为T类型的表达式

在以下任何情况下,非常量值x可转换为T型:

  • x可分配给T
  • x的类型和T具有相同的基础类型
  • x的type和T是未命名的指针类型,它们的指针基类型具有相同的底层类型
  • x的类型和T都是整数或浮点类型
  • x型和T型都是复杂类型
  • x是一个整数或字节片段或符文,T是字符串类型
  • x是一个字符串,T是一个字节或符文片段
  • 但是


    不是任何情况1-7。

    我假设:如果您通过浏览器发送JSON值,那么您发送的任何数字都将是float64类型,因此您无法在golang中直接获取int值

    因此,进行如下转换:

    //As that says: 
    fmt.Fprintf(w, "Type = %v", val) // <--- Type = float64
    
    var iAreaId int = int(val.(float64))
    
    //正如上面所说:
    
    fmt.Fprintf(w,“Type=%v”,val)/我完全同意的类型断言的答案,我非常喜欢这种方式。这就是说,当首选方法不起作用时,我不得不这么做。。。(与数据的交叉序列化相关的长篇大论)。您甚至可以使用
    case errInt==nil
    和类似的表达式将其链接到
    switch
    语句中

    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)
    最好通过声明f是对应于JSON的正确类型来避免强制转换。

    您需要执行类型断言以将接口{}转换为int值

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

    更多信息是。

    我编写了一个库,可以帮助进行类型转换


    我做这件事的最简单方法。不是最好的方法,而是我知道的最简单的方法

    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
    }
    

    添加另一个使用
    开关的答案
    。。。还有更全面的例子,但这会给你一个想法

    例如,
    t
    成为每个
    案例
    范围内的指定数据类型。注意,您必须为一个类型中的一个类型提供一个
    案例
    ,否则
    t
    仍然是一个
    接口

    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)
    }
    
    也许你需要

    func TransToString(数据接口{})(res字符串){
    开关v:=数据(类型){
    案例64:
    res=strconv.FormatFloat(data.(float64),'f',6,64)
    案例32:
    res=strconv.FormatFloat(float64(data.(float32)),'f',6,32)
    案例int:
    res=strconv.FormatInt(int64(data.(int)),10)
    案例int64:
    res=strconv.FormatInt(数据(int64),10)
    案例uint:
    res=strconv.FormatUint(uint64(数据(uint)),10)
    案例uint64:
    res=strconv.FormatUint(数据(uint64),10)
    案例32:
    res=strconv.FormatUint(uint64(data.(uint32)),10)
    案例编号:
    res=data.(json.Number).String()
    大小写字符串:
    res=数据(字符串)
    大小写[]字节:
    res=字符串(v)
    违约:
    res=“”
    }
    返回
    }
    
    回答得好!语言规范始终是寻找答案的最佳场所!谢谢这是一个很好的答案。正如所指出的,如果解析JSON,值将是float。在这种情况下,请改用strconv.ParseFloat(v.(string),64)
    。您可能还想更改变量名,比如说
    errFloat
    。您在@Mujibur上是100%正确的,但不管什么原因,因为JSON中有整数类型specs@kamal这是因为JSON使用Javascript语法和定义。JavaScript只支持64位浮点数。参考#对于
    大小写字符串
    ,可以使用
    strconv.ParseFloat(t,32)
    ,然后将结果强制转换为
    int
    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
    }
    
    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)
    }