Saya mencoba mendapatkan nilai dari JSON dan memasukkannya ke int tetapi tidak berhasil, dan saya tidak tahu cara melakukannya dengan benar.
Inilah pesan kesalahannya:
...cannot convert val (type interface {}) to type int: need type assertion
Dan kodenya:
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
Saya berasumsi: Jika Anda mengirim nilai JSON melalui browser maka nomor yang Anda kirim itu akan menjadi tipe float64 sehingga Anda tidak bisa mendapatkan nilai langsung int di golang.
Jadi lakukan konversi seperti:
//As that says: fmt.Fprintf(w, "Type = %v", val) // <--- Type = float64 var iAreaId int = int(val.(float64))
Dengan cara ini Anda bisa mendapatkan nilai yang Anda inginkan.
sumber
Menambahkan jawaban lain yang menggunakan
switch
... Ada contoh yang lebih komprehensif di luar sana, tapi ini akan memberi Anda gambaran.Misalnya,
t
menjadi tipe data yang ditentukan dalam setiapcase
cakupan. Catatan, Anda harus menyediakancase
hanya untuk satu tipe pada satu tipe, jika tidakt
tetap sebuahinterface
.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) }
sumber
case string
, Anda dapat menggunakanstrconv.ParseFloat(t, 32)
dan kemudian mengirimkan hasilnya keint
Aku sepenuh hati setuju dengan zzzz 's jenis pernyataan jawaban dan saya sangat suka dengan cara itu atas orang lain. Yang mengatakan, inilah yang harus saya lakukan ketika metode yang disukai tidak berhasil ... (cerita panjang terkait dengan lintas serialisasi data). Anda bahkan dapat merangkai ini menjadi
switch
pernyataan dengancase errInt == nil
dan ekspresi serupa.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 */ } }
Seperti yang saya katakan di atas, coba ketik pernyataan terlebih dahulu sebelum mencoba cara ini.
sumber
strconv.ParseFloat(v.(string), 64)
saja. Anda mungkin ingin mengubah nama variabel juga, katakanlaherrFloat
.Untuk lebih memahami jenis konversi, lihat kode di bawah ini:
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) }
Kode ini dijalankan dengan sempurna dan mengubah tipe antarmuka menjadi tipe int
Kembali ke kode Anda, ini
iAreaId := val.(int)
harus bekerja dengan baik. Jika Anda ingin memeriksa kesalahan yang terjadi saat konversi, Anda juga dapat menulis ulang baris di atas sebagai
iAreaId, ok := val.(int)
sumber
Saya menulis perpustakaan yang dapat membantu dengan jenis konversi 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]
sumber
Cara paling sederhana saya melakukan ini. Bukan cara terbaik tapi cara paling sederhana yang saya tahu caranya.
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 }
sumber
Anda perlu melakukan pernyataan tipe untuk mengubah antarmuka Anda {} menjadi nilai int.
iAreaId := val.(int) iAreaId, ok := val.(int)
Informasi lebih lanjut tersedia .
sumber
mungkin kamu butuh
func TransToString(data interface{}) (res string) { switch v := data.(type) { case float64: res = strconv.FormatFloat(data.(float64), 'f', 6, 64) case float32: res = strconv.FormatFloat(float64(data.(float32)), 'f', 6, 32) case int: res = strconv.FormatInt(int64(data.(int)), 10) case int64: res = strconv.FormatInt(data.(int64), 10) case uint: res = strconv.FormatUint(uint64(data.(uint)), 10) case uint64: res = strconv.FormatUint(data.(uint64), 10) case uint32: res = strconv.FormatUint(uint64(data.(uint32)), 10) case json.Number: res = data.(json.Number).String() case string: res = data.(string) case []byte: res = string(v) default: res = "" } return }
sumber
Sebaiknya hindari casting dengan menyatakan f sebagai f adalah tipe yang benar untuk menyesuaikan dengan JSON.
sumber