2013-08-19 7 views

उत्तर

4

आप एक व्यावहारिक समाधान के लिए देख रहे हैं, इस सवाल का जवाब आसान और कष्टप्रद है। reflect.TypeOf एक खाली इंटरफ़ेस प्रकार लेता है जिसमें आप जो भी डेटा पास करना चाहते हैं उसे डालते हैं। इसके साथ समस्या यह है कि एक इंटरफ़ेस प्रकार किसी अन्य इंटरफ़ेस प्रकार को नहीं रख सकता है, जिसका अर्थ है कि आप प्रभावी रूप से reflect.TypeOf पर इंटरफ़ेस पास नहीं कर सकते हैं। एक कामकाज है, लेकिन यह थोड़ा दर्दनाक है। आपको क्या करना है एक समग्र प्रकार (जैसे संरचना या टुकड़ा या नक्शा) बनाना है, जहां तत्व प्रकारों में से एक इंटरफेस प्रकार है, और इसे निकालें। उदाहरण के लिए:

var sliceOfEmptyInterface []interface{} 
var emptyInterfaceType = reflect.TypeOf(sliceOfEmptyInterface).Elem() 

पहले []interface{} के reflect.Type प्रतिनिधित्व (interface{} प्रकार का एक टुकड़ा) बनाता है और फिर तत्व प्रकार है, जो interface{} है निकालता है।

this post के सौजन्य।

5

अच्छा सवाल। मैंने खुद को खोजने के लिए लगभग एक घंटे तक काम किया! इस कोड के साथ

आइए शुरू:

package main 

import (
     "fmt" 
     "reflect" 
) 

// define an interface 
type Doer interface { 
     Do() 
} 

// define a type that implements the interface 
type T struct{} 

func (T) Do() {} 

func main() { 
     var v Doer = T{} 
     fmt.Println(reflect.TypeOf(v).Kind()) 
} 

उत्पादन struct, नहीं interface है। (You can run it here.)

ऐसा इसलिए है क्योंकि भले ही हम एक अंतरफलक के रूप v परिभाषित चर, वास्तविक मूल्य इस चर धारण प्रकार T की है। इसे चर के "गतिशील प्रकार" कहा जाता है। पैकेज reflect के मुख्य बिंदुओं में से एक गतिशील प्रकार के इंटरफ़ेस चर निर्धारित करने में मदद करना है, इसलिए यह आपको गतिशील प्रकार देता है, इंटरफ़ेस नहीं। (और अगर यह करना चाहता था, पैकेज reflect नहीं TypeOf और ValueOf के लिए पारित चर के इंटरफेस मिल सकता है, क्योंकि चर कार्यों के लिए मूल्यों के रूप में पारित कर रहे हैं।)

तो, आप देख सकते हैं अपने प्रश्न है कि, "जो मूल्य का दया Interface है? ", तकनीकी रूप से उत्तर दिया जा सकता है" नहीं मूल्य "।

लेकिन क्या Interface तब के लिए अच्छा है? यह कोड देखें:

// assuming the above code, just with this main function 
func main() { 
     a := make([]Doer, 0) 
     fmt.Println(reflect.TypeOf(a).Elem().Kind()) 
} 

यह प्रिंट interface है। (This one is here.) बिंदु Elem फ़ंक्शन में है, जो एक मानचित्र के तत्वों का प्रकार देता है, यहां एक इंटरफ़ेस प्रकार है। Elem पॉइंटर्स, सरणी, स्लाइस और चैनल पर भी काम करता है। मानचित्र की कुंजी (Key), एक struct के क्षेत्रों (Field और दोस्तों) के प्रकार के प्राप्त करने के लिए समान कार्य कर रहे हैं, और एक समारोह के तर्कों और वापसी पैरामीटर (In और Out)। आप इन सभी से प्रकार के प्रकार के इंटरफ़ेस प्राप्त करने की उम्मीद कर सकते हैं।

रोब पाईक एक भयानक लेख, The Laws of Reflection, कि इंटरफेस और प्रतिबिंब बहुत अच्छी तरह से बताते हैं लिखा था।

+2

सोमवार 1 9 अगस्त 2013: आज मैंने कुछ सीखा। – thwd

+0

कुछ चीजें: _ "पैकेज प्रतिबिंब के मुख्य बिंदुओं में से एक गतिशील प्रकार के इंटरफ़ेस चर निर्धारित करने में मदद करना है" _ - यह उस तंत्र का हिस्सा है जिसके माध्यम से प्रतिबिंबित पैकेज काम करता है। प्रतिबिंबित पैकेज का बिंदु प्रोग्रामिंग को सक्षम करता है जो कोड संरचना को दर्शाता है (प्रतिबिंबित करता है)। _ "किस मान का प्रकार इंटरफ़ेस है? तकनीकी रूप से किसी भी मूल्य के साथ उत्तर दिया जा सकता है।" _ - उत्तर बस "इंटरफ़ेस मान" है।_ "बिंदु एलेम में है, जो नक्शा के तत्वों का प्रकार लौटाता है" _ - आपके पास क्या नक्शा नहीं है, और शून्य मामलों की स्लाइस बनाना अधिकांश मामलों में अनावश्यक है। –

+0

अंक गुस्तावो के लिए धन्यवाद। – Mostafa

2

मुझे लगता है कि आपका प्रश्न बराबर है: क्या इंटरफ़ेस में कोई अन्य इंटरफ़ेस हो सकता है?

The Laws of Reflection में हम इस

एक इंटरफेस चर कोई ठोस स्टोर कर सकते हैं (गैर इंटरफेस) मूल्य

पाते हैं या फिर और अधिक विस्तार

इंटरफ़ेस प्रकार दुकानों में से एक चर में एक जोड़ी: ठोस मूल्य चर को असाइन किया गया है, और उस मान के प्रकार वर्णनकर्ता। अधिक सटीक होना, मूल्य अंतर्निहित ठोस डेटा आइटम कि इंटरफ़ेस लागू करता है और प्रकार है कि आइटम से भरा प्रकार का वर्णन करता है।

तो एक इंटरफ़ेस में कोई अन्य इंटरफ़ेस नहीं हो सकता है। इसका मतलब है कि कोई मूल्य नहीं है जिसका reflect.Kindreflect.Interface है। मुझे लगता है कि आप असुरक्षित के साथ एक बनाने में सक्षम हो सकते हैं, लेकिन मुझे नहीं लगता कि आप कभी भी सामान्य रूप से देखेंगे।

+0

_ "इसका मतलब है कि कोई मूल्य नहीं है जिसका प्रतिबिंबित होता है। किंड प्रतिबिंबित होता है। इंटरफेस" _ - इंटरफ़ेस मानों का प्रकार इंटरफ़ेस होता है, भले ही आप उन्हें किसी अन्य इंटरफ़ेस मान में स्टोर कर सकें या नहीं। ये ऑर्थोगोनल अवधारणाएं हैं। –

+0

मैंने मूल प्रश्न इस प्रकार पढ़ा है: क्या आप एक वी घोषित कर सकते हैं (प्रतिबिंबित या असुरक्षित का उपयोग नहीं कर रहे) जैसे कि 'प्रतिबिंबित करें। टाइप करें) vind() "प्रतिबिंबित करें। इंटरफेस'। उस मामले में मुझे लगता है कि मेरा बयान सत्य है। हालांकि मैं एक counterexample देखने का आनंद लेंगे ;-) –

6

उत्तर अब तक आश्चर्यजनक रूप से दृढ़ दिखते हैं, जब प्रश्न और इसकी प्रतिक्रिया वास्तव में सरल है: प्रतिबिंबित करें। इंटरफेस इंटरफ़ेस मानों का प्रकार है।

आप आसानी से देख सकते हैं कि साथ:

var v interface{} 
var t = reflect.ValueOf(&v).Type().Elem() 
fmt.Println(t.Kind() == reflect.Interface) 

ध्यान दें कि ValueOf(v) क्योंकि आप वी ही है, उसकी सामग्री के प्रकार चाहते हैं काम नहीं होगा।

2

यह आप "मूल्य" और "मूल्य की तरह" से क्या मतलब है पर निर्भर करता है।

जाओ में, "प्रकार" अलग अलग बातें मतलब हो सकता है: - स्थिर प्रकार एक अभिव्यक्ति की (संकलन समय प्रकार)। भाषा में प्रत्येक अभिव्यक्ति का एक स्थिर प्रकार संकलन समय पर जाना जाता है। - गतिशील इंटरफ़ेस मान का प्रकार (रनटाइम प्रकार)। इंटरफ़ेस प्रकार का एक चर या अभिव्यक्ति विशेष है जिसमें यह विभिन्न प्रकार के मान रख सकता है, और इस अंतर्निहित मान का प्रकार संकलन-समय पर ज्ञात नहीं है। रनटाइम पर यह रनटाइम मान और उसके प्रकार का निरीक्षण किया जा सकता है।

प्रतिबिंब क्रम में होता है, तो यह एक अंतरफलक मूल्य के गतिशील प्रकार के बारे में पूछने के लिए केवल रोचक है। इस प्रकार, आपको इंटरफेस मान के अंतर्निहित मूल्य के प्रकार के बारे में बात करनी होगी।

एक गैर-nil इंटरफ़ेस मान मूल रूप से अंतर्निहित मान और प्रकार के आस-पास "रैपर" होता है। ध्यान दें कि यह अंतर्निहित प्रकार एक इंटरफ़ेस प्रकार नहीं हो सकता है। यानी रैपर एक और रैपर "लपेट" नहीं सकता है। यह जोश्लफ 13 का जवाब कह रहा है। ऐसा इसलिए है क्योंकि जब आप एक इंटरफ़ेस प्रकार से दूसरे इंटरफ़ेस प्रकार में असाइन करते हैं, केवल अंतर्निहित मान स्थानांतरित होता है। इंटरफेस प्रकार से आया यह याद नहीं है। इस प्रकार, एक इंटरफ़ेस मान बनाना असंभव है जिसका अंतर्निहित प्रकार एक इंटरफ़ेस प्रकार है।

प्रतिबिंब कार्यों जैसे reflect.ValueOf() और reflect.TypeOf() आपको इंटरफ़ेस मान में जाने दें और अंतर्निहित मान का प्रतिनिधित्व प्राप्त करें। पैरामीटर प्रकार interface{} है क्योंकि यह वह प्रकार है जो आपको कुछ भी पारित करने की अनुमति देता है। हालांकि, वे मानते हैं कि आप वास्तव में उस इंटरफ़ेस मान के अंतर्निहित मूल्य में दिलचस्प हैं, जिसे आप पहले स्थान पर पास करके interface{} में बदल गए हैं, या आप इसे कहीं और से प्राप्त कर चुके हैं और इसकी जांच करना चाहते हैं। इस प्रकार, प्रतिबिंब कार्य मूल रूप से इंटरफेस के अंतर्निहित मूल्य की जांच के लिए होते हैं (जो ऊपर बताया गया है, गैर-इंटरफ़ेस प्रकार का होना चाहिए), और वास्तविक इंटरफ़ेस प्रकार तर्क नहीं।

इसलिए, यदि आपका प्रश्न है: vreflect.ValueOf(v).Kind()Interface का मूल्यांकन कर सकता है; जवाब कुछ भी नहीं है। ऐसा इसलिए है क्योंकि, vnil नहीं है, तो ValueOf() को इसके अंतर्निहित मूल्य का प्रतिनिधित्व मिलता है, जो गैर-इंटरफ़ेस प्रकार का होना चाहिए। और यदि vnil है, तो reflect.ValueOf() के प्रलेखन द्वारा, यह Value प्रकार का शून्य मान देता है, और Value.Kind() प्रकार के लिए प्रलेखन का कहना है कि शून्य मूल्य पर Kind() पर कॉलिंग Invalid है।

-1

मैं इसके लिए एक स्पष्ट उत्तर दूंगा।

सबसे पहले आपको कुछ इंटरफ़ेस किसी अन्य इंटरफ़ेस को छोड़कर कुछ भी पकड़ सकता है। तो चलिए इसे स्पष्ट करते हैं। इस कार्यक्रम को देखो।

type i interface { 
    hello() 
} 
type s struct{ 
name string 
} 
func (a s)hello(){} 
func main(){ 
    var f i //here we create an empty interface i 
    f=s{} //now f hold a structure of type s 
    fmt.Print(reflect.ValueOf(f).Kind()) // here we got a structure type so what really happen now i will explained 
    } 

valueOf methode के हस्ताक्षर है:

reflect.ValueOf(i interface{}) 

तो valueOf हमेशा एक ampty इंटरफ़ेस क्या मैं तुम्हें कभी नहीं इंटरफेस अन्य इंटरफेस पकड़ इतना कहा था मिलता है। valueOf एफ इंटरफ़ेस नहीं लेगा, लेकिन यह एक खाली इंटरफ़ेस लेगा जो संरचना को पकड़ता है। की तरह अगर हम च के अंतर्निहित कीमत taked और valueOf methode के लिए एक खाली इंटरफ़ेस करने के लिए सौंपा और

0

आप सीधे एक interface{} मूल्य के प्रकार नहीं मिल सकता है पारित कर दिया यह है, लेकिन आप एक सूचक अविवेक के माध्यम से जाना कर सकते हैं:

reflect.TypeOf(new(interface{})).Elem() 

भागो इस on play.golang.org:

t := reflect.TypeOf(new(interface{})).Elem() 
fmt.Printf("Type: %s\n", t) 
fmt.Printf("Kind: %v\n", t.Kind()) 
fmt.Printf("IsInterface: %v\n", t.Kind() == reflect.Interface) 

आउटपुट:

Type: interface {} 
Kind: interface 
IsInterface: true 
संबंधित मुद्दे