समस्या है कि यहाँ shower
एक interface
प्रकार है। गो में इंटीफेस प्रकार वास्तविक मान रखते हैं और इसके गतिशील प्रकार। इसके बारे में अधिक जानकारी: The Laws of Reflection #The representation of an interface।
आपके द्वारा लौटाई गई टुकड़ा में 2 गैर- nil
मान शामिल हैं। दूसरा मान एक इंटरफ़ेस मान है, एक (मान; प्रकार) जोड़ी nil
मान और *display
प्रकार है। Go Language Specification: Comparison operators से क्यूटोइंग:
इंटरफ़ेस मान तुलनीय हैं। दो इंटरफ़ेस मान बराबर होते हैं यदि उनके पास समान गतिशील प्रकार और समान गतिशील मान होते हैं या दोनों के पास nil
मान है।
तो यदि आप इसकी तुलना nil
से करते हैं, तो यह false
होगा। आप जोड़ी (nil;*display)
का प्रतिनिधित्व एक अंतरफलक मूल्य की तुलना करते हैं, यह true
हो जाएगा:
if x == (*display)(nil) {
panic("everything ok, nil found")
}
यह unfeasable लगता है के रूप में आप वास्तविक प्रकार इंटरफ़ेस रखती है पता करने के लिए होगा।
इस तरह इसे क्यों लागू किया गया है?
अन्य ठोस प्रकारों (गैर-इंटरफेस) के विपरीत इंटरफेस विभिन्न ठोस प्रकारों (विभिन्न स्थिर प्रकार) के मूल्य रख सकते हैं। रनटाइम को इंटरफ़ेस प्रकार के चर में संग्रहीत मान के गतिशील या रनटाइम-प्रकार को जानने की आवश्यकता होती है।
एक interface
सिर्फ एक विधि सेट, किसी भी प्रकार यह लागू करता है, तो एक ही तरीके का प्रकार का method set का हिस्सा हैं है। ऐसे प्रकार हैं जो nil
नहीं हो सकते हैं, उदाहरण के लिए struct
या int
के साथ एक कस्टम प्रकार इसके अंतर्निहित प्रकार के रूप में। इन मामलों में आपको उस विशिष्ट प्रकार के nil
मान को स्टोर करने में सक्षम होने की आवश्यकता नहीं होगी।
लेकिन किसी भी प्रकार भी ठोस प्रकार जहां nil
कोई मान्य मान है (उदाहरण के स्लाइस, नक्शे, चैनलों, सभी सूचक प्रकार) शामिल हैं, इसलिए क्रम में है कि इंटरफ़ेस इसे समर्थन करने के लिए उचित है संतुष्ट करता रनटाइम पर मान संग्रहीत इंटरफ़ेस के अंदर nil
संग्रहित करना। लेकिन इंटरफ़ेस के अंदर nil
के अलावा हमें इसके गतिशील प्रकार को स्टोर करना होगा क्योंकि nil
मान ऐसी जानकारी नहीं लेता है। वैकल्पिक विकल्प nil
का उपयोग इंटरफ़ेस मान के रूप में करना होगा जब उसमें संग्रहीत मूल्य nil
है, लेकिन यह समाधान अपर्याप्त है क्योंकि यह गतिशील प्रकार की जानकारी खो देगा।
कुछ लोग कहते हैं कि गो के इंटरफेस गतिशील रूप से टाइप किए गए हैं, लेकिन यह भ्रामक है। वे स्थिर रूप से टाइप किए गए हैं: इंटरफ़ेस प्रकार का एक चर हमेशा एक ही स्थिर प्रकार होता है, और भले ही रन टाइम पर इंटरफ़ेस चर में संग्रहीत मान प्रकार बदल सकता है, वह मान हमेशा इंटरफ़ेस को संतुष्ट करेगा।
सामान्य तौर पर आप, interface
प्रकार का एक मूल्य के लिए nil
दर्शाना चाहते हैं स्पष्ट nil
मान का उपयोग करें और फिर आप nil
समानता के लिए परीक्षण कर सकते हैं यदि। सबसे आम उदाहरण अंतर्निहित error
प्रकार है जो एक विधि के साथ एक इंटरफ़ेस है। जब भी कोई त्रुटि नहीं होती है, तो आप मूल्य nil
को स्पष्ट रूप से सेट या वापस कर देते हैं और कुछ कंक्रीट (गैर-इंटरफेस) प्रकार त्रुटि चर का मूल्य नहीं (जो वास्तव में खराब अभ्यास होगा, नीचे प्रदर्शन देखें)।
अपने उदाहरण में भ्रम की स्थिति तथ्यों से उत्पन्न होती है कि:
- आप एक इंटरफेस प्रकार के रूप में एक मूल्य करना चाहते हैं (
shower
)
- लेकिन मूल्य आप टुकड़ा में संग्रहीत करना चाहते हैं की नहीं है प्रकार
shower
लेकिन एक ठोस प्रकार
तो जब आप shower
टुकड़ा में एक *display
प्रकार शब्दों में कहें, एक अंतरफलक मूल्य बनाया जाएगा, जो की एक जोड़ी है (मूल्य; प्रकार) जहां मूल्य ०१२३४६१५१७ हैऔर प्रकार *display
है। जोड़ी के अंदर मूल्यnil
होगा, न कि इंटरफ़ेस मूल्य स्वयं। यदि आप स्लाइस में nil
मान डाल देंगे, तो इंटरफ़ेस मान स्वयंnil
होगा और एक स्थिति x == nil
true
होगी। Playground
type MyErr string
func (m MyErr) Error() string {
return "big fail"
}
func doSomething(i int) error {
switch i {
default:
return nil // This is the trivial true case
case 1:
var p *MyErr
return p // This will be false
case 2:
return (*MyErr)(nil) // Same as case 1
case 3:
var err error // Zero value is nil for the interface
return err // This will be true because err is already interface type
case 4:
var p *MyErr
return error(p) // This will be false because the interface points to a
// nil item but is not nil itself.
}
}
func main() {
for i := 0; i <= 4; i++ {
err := doSomething(i)
fmt.Println(i, err, err == nil)
}
}
आउटपुट::
0 <nil> true
1 <nil> false
2 <nil> false
3 <nil> true
4 <nil> false
मामले 2 में एक nil
सूचक दिया जाता है, लेकिन पहले यह एक इंटरफ़ेस प्रकार में बदल जाती है (
प्रदर्शन
इस उदाहरण देखें error
) तो एक इंटरफ़ेस मान बनाया गया है जिसमेंहैमान और प्रकार *MyErr
, इसलिए इंटरफ़ेस मान nil
नहीं है।
यह एक त्रुटि के रूप में 'त्रुटि' इंटरफ़ेस का उपयोग करते हुए FAQ में है: https://golang.org/doc/faq#nil_error – JimB