कन्वर्ट इंटरफ़ेस {} को int


97

मैं एक JSON से मान प्राप्त करने का प्रयास कर रहा हूं और इसे इंट में डालना चाहता हूं लेकिन यह काम नहीं करता है, और मुझे नहीं पता कि यह कैसे ठीक से करना है।

यहाँ त्रुटि संदेश है:

...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

जवाबों:


193

के बजाय

iAreaId := int(val)

आप एक प्रकार का दावा चाहते हैं :

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

इंटरफ़ेस टाइप किए गए मान को परिवर्तित नहीं कर पाने का कारण यह है कि संदर्भित निर्दिष्ट भागों में ये नियम हैं:

रूपांतरण उस रूप के भाव हैं T(x)जहां Tएक प्रकार है और xएक अभिव्यक्ति है जिसे टाइप टी में परिवर्तित किया जा सकता है।

...

एक गैर-स्थिर मान x को इनमें से किसी भी मामले में टाइप T में परिवर्तित किया जा सकता है:

  1. x, T के लिए उत्तरदायी है।
  2. एक्स के प्रकार और टी में समान अंतर्निहित प्रकार होते हैं।
  3. x का प्रकार और T अनाम सूचक प्रकार हैं और उनके सूचक आधार प्रकार में समान अंतर्निहित प्रकार होते हैं।
  4. x का प्रकार और T दोनों पूर्णांक या फ्लोटिंग बिंदु प्रकार हैं।
  5. x का प्रकार और T दोनों जटिल प्रकार हैं।
  6. x एक पूर्णांक या बाइट्स या रनों का एक टुकड़ा है और T एक स्ट्रिंग प्रकार है।
  7. x एक स्ट्रिंग है और T बाइट्स या रनों का एक टुकड़ा है।

परंतु

iAreaId := int(val)

1 -7 में से कोई भी मामला नहीं है


अच्छा उत्तर! उत्तर की तलाश के लिए भाषा की कल्पना हमेशा सबसे अच्छी जगह है!
Hot.PxL

धन्यवाद। यह एक सुंदर जवाब है।
मुक्तादिर

29

मैं मान रहा हूँ: यदि आपने JSON मान को ब्राउज़र के माध्यम से भेजा है, तो आपके द्वारा भेजा गया कोई भी प्रकार फ़्लोट64 होगा ताकि आप उस मूल्य को सीधे गोलंग में प्राप्त कर सकें।

इसलिए रूपांतरण जैसे:

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

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

इस तरह से आप सटीक मूल्य प्राप्त कर सकते हैं जो आप चाहते थे।


तुम्हें पता है, 100% सही @Mujibur, लेकिन किसी भी कारण के रूप में में JSON चश्मा प्रकार पूर्णांक है
कमल

@kamal ऐसा इसलिए है क्योंकि JSON, जावास्क्रिप्ट सिंटैक्स और परिभाषाओं का उपयोग करता है। जावास्क्रिप्ट केवल 64-बिट फ्लोटिंग पॉइंट नंबरों का समर्थन करता है। Ref # javascript.info/number
मुजीबुर

4

एक और उत्तर जो उपयोग करता है, को जोड़ना 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)
}

के लिए case string, आप उपयोग कर सकते हैं strconv.ParseFloat(t, 32)और फिर परिणाम को एकint
JVE999

3

मैं पूरे दिल से सहमत हूं 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 */
    }
}

जैसा कि मैंने ऊपर कहा है, इस तरह की कोशिश करने से पहले पहले टाइप करने का प्रयास करें।


जैसा कि बताया गया है, अगर JSON को पार्स किया जाता है, तो मान फ्लोट होगा। उस स्थिति में, strconv.ParseFloat(v.(string), 64)इसके बजाय का उपयोग करें । आप चर नाम भी बदलना चाह सकते हैं, कहते हैं errFloat
ओपनवॉक

0

प्रकार रूपांतरण को बेहतर ढंग से समझने के लिए, नीचे दिए गए कोड को देखें:

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 प्रकार में परिवर्तित करता है

इंटरफ़ेस प्रकार और एक्स प्रकार की अभिव्यक्ति एक्स के लिए, प्राथमिक अभिव्यक्ति एक्स (टी) का दावा है कि एक्स शून्य नहीं है और यह कि एक्स में संग्रहीत मूल्य टी टाइप है। नोटेशन एक्स। (टी) को एक प्रकार का अभिकथन कहा जाता है। । अधिक सटीक रूप से, यदि T एक इंटरफ़ेस प्रकार नहीं है, तो x (T) यह बताता है कि x का गतिशील प्रकार T के प्रकार के समान है। इस स्थिति में, T को x का इंटरफ़ेस (इंटरफ़ेस) प्रकार लागू करना चाहिए; अन्यथा प्रकार अभिकथन अमान्य है क्योंकि x के लिए यह संभव नहीं है कि टाइप T का मान संग्रहीत किया जाए। यदि T एक प्रकार का प्रकार है, तो x (T) इस बात का दावा करता है कि गतिशील प्रकार x इंटरफ़ेस को लागू करता है।

अपने कोड पर वापस जा रहे हैं, यह

iAreaId := val.(int)

अच्छा काम करना चाहिए। यदि आप रूपांतरण करते समय हुई त्रुटि की जाँच करना चाहते हैं, तो आप पंक्ति के ऊपर भी फिर से लिख सकते हैं

iAreaId, ok := val.(int)


0

मैंने एक लाइब्रेरी लिखी है जो टाइप कन्वर्जन 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]

0

सबसे सरल तरीका मैंने ऐसा किया। सबसे अच्छा तरीका नहीं है लेकिन सबसे सरल तरीका मुझे पता है कि कैसे।

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
}

0

आपको अपने इंटरफ़ेस {} को अंतर मान में परिवर्तित करने के लिए टाइप करने की आवश्यकता है।

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

अधिक जानकारी उपलब्ध है


0

शायद आपको चाहिए

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
}

-2

JSON के अनुरूप करने के लिए f को सही प्रकार घोषित करके कास्टिंग से बचें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.