2013-08-04 12 views
59

Sono nuovo in Golang e sto cercando di ottenere un valore da un JSON e lo lancio su int ma non funziona. Non so come farlo correttamente.converte l'interfaccia {} in int in Golang

Ecco il messaggio di errore:

...cannot convert val (type interface {}) to type int: need type assertion 

e al codice:

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 

qualsiasi aiuto sarebbe apprezzato.

risposta

108

Invece di

iAreaId := int(val) 

si desidera un type assertion:

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

Il motivo per cui non è possibile convert un valore un'interfaccia tipizzato sono queste regole nelle parti Specifiche di riferimento:

Le conversioni sono espressioni del modulo T(x) dove T è un tipo e x è un'espressione che può essere convertito nel tipo T.

...

Un valore non costante x può essere convertito nel tipo T in qualsiasi di questi casi:

  1. x è assegnabile a T.
  2. tipo
  3. da x e T hanno tipi sottostanti identici.
  4. Il tipo e T di x sono tipi di puntatori senza nome e i loro tipi di base puntatori hanno identici tipi sottostanti.
  5. Il tipo e T di x sono tipi interi o in virgola mobile.
  6. tipo di x e T sono entrambi tipi complessi.
  7. x è un numero intero o una porzione di byte o di rune e T è un tipo di stringa.
  8. x è una stringa e T è una porzione di byte o di rune.

Ma

iAreaId := int(val) 

non è nessuno dei casi 1.-7.

+0

Buona risposta! Le specifiche della lingua sono sempre il posto migliore per cercare una risposta! –

+0

Grazie. è una bella risposta. – Muktadir

+0

Non la risposta corretta per l'input JSON. Vedi sotto. – Liam

11

Sto assumendo: Se hai inviato il valore JSON tramite browser, qualsiasi numero che hai inviato sarà il tipo float64, quindi non puoi ottenere direttamente il valore int in golang.

in modo da fare la conversione del tipo:

// Come che dice: fmt.Fprintf (w, "Type =% v", val) // --- < Type = float64

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

In questo modo è possibile ottenere il valore esatto di ciò che si desidera.

1

Sono pienamente d'accordo con zzzz 's asserzione di tipo risposta e io preferisco fortemente in questo modo rispetto agli altri. Detto questo, ecco cosa ho dovuto fare quando il metodo preferito non ha funzionato ... (lunga storia relativa alla serializzazione incrociata dei dati). Puoi anche associarlo a una dichiarazione switch con case errInt == nil e espressioni simili.

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

Come ho detto sopra, provare tipo affermazione prima prima di provare questo modo.

0

Per comprendere meglio la conversione di tipo, guardare il codice qui sotto:

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

Questo codice esegue perfettamente e converte tipo di interfaccia a int tipo

Per un'espressione x di tipo di interfaccia e un digitare T, l'espressione primaria x. (T) asserisce che x non è nullo e che il valore memorizzato in x è di tipo T. La notazione x. (T) è chiamata tipo asserzione. Più precisamente, se T non è un tipo di interfaccia, x. (T) asserisce che il tipo dinamico di x è identico al tipo T. In questo caso, T deve implementare il tipo (di interfaccia) di x; altrimenti l'affermazione del tipo non è valida poiché non è possibile per x memorizzare un valore di tipo T. Se T è un tipo di interfaccia, x. (T) asserisce che il tipo dinamico di x implementa l'interfaccia T.

Tornando al codice, questa

iAreaId := val.(int)

dovrebbe funzionare bene. Se si desidera controllare Errore durante la conversione, si può anche riscrivere sopra la linea come

iAreaId, ok := val.(int)

-1

migliore fusione evitano dichiarando di essere f f del tipo corretto per far corrispondere la JSON.

0

È necessario eseguire il tipo di asserzione per convertire l'interfaccia {} in valore int.

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

Altre informazioni sono available.