मैं गो से अपेक्षाकृत परिचित हूं, इसमें कई छोटे कार्यक्रम लिखे हैं। जंग, ज़ाहिर है, मैं कम परिचित हूं, लेकिन नज़र रखता हूं।
हाल ही में पढ़े गए http://yager.io/programming/go.html पर , मुझे लगा कि मैं व्यक्तिगत रूप से उन दो तरीकों की जांच करूंगा, जिन्हें जेनरिक ने संभाला है क्योंकि लेख को गलत तरीके से आलोचना करना प्रतीत होता है, जब व्यवहार में जाएं, तो ऐसा नहीं था कि इंटरफेसेस सुरुचिपूर्ण ढंग से पूरा नहीं कर सका। मैं प्रचार के बारे में सुनता रहा कि रस्ट के लक्षण कितने शक्तिशाली थे और गो के बारे में लोगों की आलोचना के अलावा कुछ नहीं। गो में कुछ अनुभव होने के बाद, मैं सोचता था कि यह कितना सच था और आखिरकार क्या अंतर था। मैंने पाया कि ट्रेट्स और इंटरफेस बहुत समान हैं! अंत में, मुझे यकीन नहीं है कि अगर मुझे कुछ याद आ रहा है, तो यहां उनकी समानता का एक त्वरित शैक्षिक ठहरनेवाला है ताकि आप मुझे बता सकें कि मैंने क्या याद किया!
अब, आइए उनके दस्तावेज़ों से Go Interfaces पर एक नज़र डालें :
गो में इंटरफेस किसी वस्तु के व्यवहार को निर्दिष्ट करने का एक तरीका प्रदान करता है: यदि कोई ऐसा कर सकता है, तो इसका उपयोग यहां किया जा सकता है।
अब तक सबसे आम इंटरफ़ेस है Stringer
जो ऑब्जेक्ट का प्रतिनिधित्व करने वाला एक स्ट्रिंग देता है।
type Stringer interface {
String() string
}
तो, इस String()
पर परिभाषित किसी भी वस्तु एक Stringer
वस्तु है। इसका उपयोग प्रकार के हस्ताक्षर में किया जा सकता है जो func (s Stringer) print()
लगभग सभी वस्तुओं को ले जाता है और उन्हें प्रिंट करता है।
हमारे पास भी interface{}
कोई वस्तु है। हमें तब प्रतिबिंब के माध्यम से रनटाइम पर प्रकार का निर्धारण करना चाहिए।
अब, चलो उनके प्रलेखन से जंग के लक्षणों पर एक नज़र डालें :
अपने सरलतम पर, एक लक्षण शून्य या अधिक विधि हस्ताक्षर का एक सेट है। उदाहरण के लिए, हम उन चीजों के लिए प्रिंट करने योग्य घोषित कर सकते हैं, जिन्हें कंसोल में मुद्रित किया जा सकता है, एक एकल विधि हस्ताक्षर के साथ:
trait Printable {
fn print(&self);
}
यह तुरंत हमारे गो इंटरफेस के समान दिखता है। एकमात्र अंतर यह है कि हम केवल तरीकों को परिभाषित करने के बजाय लक्षणों के 'कार्यान्वयन' को परिभाषित करते हैं। तो, हम करते हैं
impl Printable for int {
fn print(&self) { println!("{}", *self) }
}
के बजाय
fn print(a: int) { ... }
बोनस प्रश्न: यदि आप किसी ऐसे फ़ंक्शन को परिभाषित करते हैं जो एक विशेषता को लागू करता है, लेकिन क्या आप उपयोग नहीं करते हैं तो क्या होता है impl
? यह सिर्फ काम नहीं करता है?
गो के इंटरफेस के विपरीत, रस्ट के सिस्टम में टाइप पैरामीटर होते हैं जो आपको उचित जेनरिक और चीजें जैसे interface{}
कि कंपाइलर और रनटाइम को वास्तव में टाइप करते हैं। उदाहरण के लिए,
trait Seq<T> {
fn length(&self) -> uint;
}
किसी भी प्रकार पर काम करता है और संकलक जानता है कि प्रतिबिंब का उपयोग करने के बजाय संकलन समय पर अनुक्रम तत्वों का प्रकार।
अब, वास्तविक प्रश्न: क्या मुझे यहाँ कोई अंतर याद आ रहा है? वे वास्तव में कर रहे हैं कि इसी तरह की? क्या कुछ और मूलभूत अंतर नहीं है जो मुझे यहाँ याद आ रहा है? (उपयोग में। कार्यान्वयन विवरण दिलचस्प हैं, लेकिन अंततः महत्वपूर्ण नहीं हैं यदि वे समान कार्य करते हैं।)
वाक्यात्मक अंतर के अलावा, मेरे द्वारा देखे जाने वाले वास्तविक अंतर इस प्रकार हैं:
- गो में स्वचालित विधि प्रेषण है। अनुगमन को
impl
लागू करने के लिए जंग (?) की आवश्यकता होती है- सुरुचिपूर्ण बनाम स्पष्ट
- जंग में प्रकार के पैरामीटर होते हैं जो प्रतिबिंब के बिना उचित जेनरिक के लिए अनुमति देते हैं।
- गो वास्तव में यहाँ कोई प्रतिक्रिया नहीं है। यह एकमात्र ऐसी चीज है जो काफी अधिक शक्तिशाली है और यह अंततः विभिन्न प्रकार के हस्ताक्षर के साथ तरीकों को कॉपी करने और चिपकाने के लिए एक प्रतिस्थापन है।
क्या ये केवल गैर-तुच्छ अंतर हैं? यदि ऐसा है, तो यह गो का इंटरफेस / टाइप सिस्टम दिखाई देगा, व्यवहार में, जैसा कि कमजोर नहीं है।
AnyMap
में रस्ट की ताकत का एक अच्छा प्रदर्शन है, जो नाजुक वस्तुओं का एक सुरक्षित और अभिव्यंजक अमूर्त प्रदान करने के लिए जेनेटिक्स के साथ विशेषता वस्तुओं का संयोजन करता है, जिसमें गो की आवश्यकता लिखी जाएगीmap[string]interface{}
।