गो

2012-07-09 12 views
60

में एकाधिक रिटर्न मानों पर रूपांतरण/प्रकार का दावा करने का बेवकूफ तरीका गो में एकाधिक रिटर्न मान डालने का बेवकूफ तरीका क्या है?गो

क्या आप इसे एक ही पंक्ति में कर सकते हैं, या आपको नीचे दिए गए उदाहरण में अस्थायी चर का उपयोग करने की आवश्यकता है?

package main 

import "fmt" 

func oneRet() interface{} { 
    return "Hello" 
} 

func twoRet() (interface{}, error) { 
    return "Hejsan", nil 
} 

func main() { 
    // With one return value, you can simply do this 
    str1 := oneRet().(string) 
    fmt.Println("String 1: " + str1) 

    // It is not as easy with two return values 
    //str2, err := twoRet().(string) // Not possible 
    // Do I really have to use a temp variable instead? 
    temp, err := twoRet() 
    str2 := temp.(string) 
    fmt.Println("String 2: " + str2) 


    if err != nil { 
     panic("unreachable") 
    } 
} 

वैसे, यह casting कहा जाता है जब यह इंटरफेस के लिए आता है?

i := interface.(int) 

उत्तर

55

आप इसे एक ही पंक्ति में नहीं कर सकते हैं। आपका अस्थायी परिवर्तनीय दृष्टिकोण जाने का तरीका है।

वैसे, क्या यह इंटरफेस की बात आती है जब इसे कास्टिंग कहा जाता है?

इसे वास्तव में type assertion कहा जाता है। एक प्रकार डाली रूपांतरण अलग है:

var a int 
var b int64 

a = 5 
b = int64(a) 
+10

असल में, इसे या तो कलाकार नहीं कहा जाता है। इसे एक रूपांतरण कहा जाता है। http://golang.org/ref/spec#Conversions –

+1

दोनों सवालों के जवाब देने के लिए धन्यवाद। मैंने इस शीर्षक को प्रश्न के लिए अधिक पर्याप्त बनाने के लिए संपादित किया है। – ANisus

11

template.Must एक बयान में केवल पहले वापसी मान लौटने के लिए मानक पुस्तकालय का दृष्टिकोण है। आपके मामले के लिए इसी तरह किया जा सकता है:

func must(v interface{}, err error) interface{} { 
    if err != nil { 
     panic(err) 
    } 
    return v 
} 

// Usage: 
str2 := must(twoRet()).(string) 

must का उपयोग कर आप मूल रूप से कहना है कि उसमें कोई त्रुटि हो कभी नहीं करना चाहिए, और अगर वहाँ है, तो कार्यक्रम नहीं (या कम से कम नहीं होना चाहिए) ऑपरेटिंग रख सकते तक , और बदले में घबराएगा।

+4

त्रुटियों पर घबराहट करना असंभव है जो प्रोग्रामर के कारण नहीं थे। 'टेम्पलेट। मस्ट()' जैसे फ़ंक्शन का उपयोग आमतौर पर पैकेज स्तर घोषणाओं और 'init()' फ़ंक्शंस में चर से टेम्पलेट लोड करने के लिए किया जाता है। विचार रनटाइम पर तुरंत घबराहट करना और यह स्पष्ट करना है कि संकलक कुछ पकड़ नहीं सकता है। अस्थायी चर से बचने के लिए आपको इसका उपयोग नहीं करना चाहिए। –

+1

और "का उपयोग करके 'का कौन सा हिस्सा आपको मूल रूप से कह सकता है कि कभी भी कोई त्रुटि नहीं होनी चाहिए" स्पष्ट नहीं था? आपको तब तक इसका उपयोग नहीं करना चाहिए जब तक कि त्रुटि केवल प्रोग्रामर के कारण न हो या प्रोग्राम में कोई त्रुटि होने पर प्रोग्राम जारी नहीं रह सकता है। –

+1

मैं असहमत हूं "या कोई त्रुटि होने पर प्रोग्राम वास्तव में जारी नहीं रह सकता"। उस स्थिति में आपको अभी भी घबराहट नहीं करनी चाहिए। –

24
func silly() (interface{}, error) { 
    return "silly", nil 
} 

v, err := silly() 
if err != nil { 
    // handle error 
} 

s, ok := v.(string) 
if !ok { 
    // the assertion failed. 
} 

लेकिन अधिक होने की संभावना क्या आप वास्तव में चाहते हैं की तरह एक यह एक प्रकार स्विच का उपयोग करने के लिए, यह है:

switch t := v.(type) { 
case string: 
    // t is a string 
case int : 
    // t is an int 
default: 
    // t is some other type that we didn't name. 
} 

जाओ शुद्धता के बारे में वास्तव में एक से अधिक यह terseness के बारे में है।

+0

फिर भी मुझे लगता है कि जाओ शुद्धता को छोड़ दिए बिना भी काफी परेशान होने में सफल होता है। इस प्रश्न को देखने वाले अन्य लोगों के लिए, मुझे लगता है कि यह अच्छा है कि आपने दावा जांच का उल्लेख किया है। मेरे मामले में हालांकि मुझे पहले से ही पता है कि इंटरफेस में किस प्रकार का संग्रह किया जाता है, इसलिए मैंने चेक छोड़ दिया। मैंने 'इंटरफ़ेस {} 'के बजाय' असुरक्षित 'सूचक का उपयोग करने के बारे में भी सोचा, लेकिन मुझे लगता है कि असुरक्षित पॉइंटर्स के उपयोग को उचित ठहराने के प्रकार में पर्याप्त ओवरहेड नहीं है। – ANisus

+1

मुझे शायद यह इंगित करना चाहिए कि ऐसा करने का बेवकूफ तरीका इंटरफ़ेस वापस नहीं करना है {}, लेकिन इनपुट पैरामीटर के रूप में इंटरफ़ेस {} को स्वीकार करने के लिए, उस प्रकार को चेक करें जिसमें पारित किया गया था, और उसके बाद उस प्रकार को भरें। यह एन्कोडिंग/जेसन पैकेज की Unmarshal विधि में काफी अच्छी तरह से उदाहरण है। ये तकनीकें सभी समान स्थितियों को कवर नहीं करती हैं, इसलिए यह हमेशा संभव नहीं हो सकता है, लेकिन अंतरफलक को वापस करने के लिए इंटरफ़ेस {} को स्वीकार करना सामान्य रूप से बेहतर है {}। आप यह सुनिश्चित करने के लिए प्रतिबिंबित पैकेज का उपयोग कर सकते हैं कि प्रदत्त मान एक सूचक है। – jorelli

2

या बस एक ही है, तो में: कलाकारों का ख्याल

if v, ok := value.(migrater); ok { 
    v.migrate() 
} 

जाओ लगेगा अगर खंड के अंदर और आप casted प्रकार के गुणों का उपयोग करते हैं।