2016-06-07 8 views
7

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

तो मैं

type MyNamedArray 
    data::Array 
    name::ASCIIString 
end 

function mywrite(f,x::MyNamedArray) 
    write(f,x.name) 
    write(f,x.data) 
end 

या कुछ और, और कोई अन्य व्यवहार आधार सरणी व्यवहार से भिन्न होने की जरूरत है क्या कर सकते हैं।

मेरे सिर में, यह "स्पष्ट" है कि मैं सिर्फ इस मौजूदा प्रकार के data पर संचालित करने के लिए Arrays पर चलने वाले प्रत्येक मौजूदा फ़ंक्शन को चाहता हूं। दूसरी भाषा में उदा। जावा मैंने शायद ऐरे को उप-वर्गीकृत किया हो और उप-वर्ग में एक उदाहरण फ़ील्ड के रूप में name जोड़ा, जो स्वचालित रूप से सभी मौजूदा ऐरे संचालन के साथ संगतता को संरक्षित रखेगा। लेकिन जूलिया में, यदि मैं उपर्युक्त समाधान का प्रयास करता हूं, तो अब मुझे एक टन और फ़ंक्शन परिभाषित करने की आवश्यकता है, उदा। @TimHoly और 'Davidavdav' के रूप में जुड़े हुए संकुल में किया है।

बेशक मुझे पता है कि इन कार्यों में से कुछ को हाथ से लिखने के लिए मजबूर होना उन चीजों को साकार करने के लिए उपयोगी है जिनके बारे में आपने सोचा नहीं है। जैसे उदाहरण में MyNamedArray मैं ऊपर देता हूं, कोई यह इंगित करके ऑब्जेक्ट कर सकता है कि मैंने x::MyNamedArray * y::MyNamedArray का नाम परिभाषित नहीं किया है। लेकिन क्या होगा यदि मुझे इसकी परवाह नहीं है, और कोड इतना चाहते हैं कि "बॉयलरप्लेट के बिना" बस काम करता है "? (उदाहरण के लिए देखें प्रतीकों के ऊपर पाशन नई विधि परिभाषाओं in NamedArrays और मैन्युअल रूप से पुश करने के लिए परिभाषाएँ in Images के एक सौ लाइनों बाहर लेखन। इन परिभाषाओं के विशाल बहुमत बॉयलरप्लेट/"स्पष्ट" परिभाषा कर रहे हैं।)

विशेष रूप से उदाहरण मैं उद्धृत जारी रखने के लिए , MyNamedArray के लिए, डिफ़ॉल्ट x*y अब MyNamedArray नहीं हो सकता है, यानी प्रत्येक कार्य केवल अंतर्निहित डेटा पर एक ही फ़ंक्शन को लागू करने के "विरासत" व्यवहार के लिए डिफ़ॉल्ट रूप से डिफ़ॉल्ट है, इसलिए हम सभी पूर्व-मौजूदा कार्यों पर मेटाडेटा को भूल सकते हैं।

नोट, मुझे टॉमस लाइकेन का जवाब here अंतर्दृष्टि मिल गया है, और ऐसे प्रश्न और उत्तर here हैं।

सबसे अच्छा संश्लेषण मैं साथ आ सकता हूं "आपको बस इसे चूसना और कार्यों को लिखना है, या एक मैक्रो लिखना है जो आपके लिए करता है।" यदि यह मामला है, तो यह हो; मैं बस सोच रहा हूं कि क्या मुझे एक बेहतर विकल्प याद आ रहा है, विशेष रूप से इसे अधिक जूलियन बनाने और बॉयलरप्लेट से बचने के लिए समाधान को डिजाइन करने का एक बेहतर तरीका है।

उत्तर

5

आप AbstractArray: http://docs.julialang.org/en/latest/manual/interfaces/#abstract-arrays को बस उपclass करके वहां से अधिकांश तरीके प्राप्त कर सकते हैं। वास्तव में, आप एक बेहतर और subclass DenseArray कर सकते हैं, जो अतिरिक्त रूप से stride (और शायद pointer) फ़ंक्शन को परिभाषित करने की आवश्यकता है ... आपके कस्टम सरणी को BLAS के साथ काम करने की अनुमति देता है। यह केवल कुछ मुट्ठी भर विधियों को परिभाषित करने की आवश्यकता है। यह 100% नहीं है क्योंकि कई लेखकों के पास अभी भी Array स्वीकार करने के तरीकों को अत्यधिक प्रतिबंधित करने की प्रवृत्ति है, जब वे आसानी से सभी AbstractArrays स्वीकार कर सकते हैं। यह ऐसा कुछ है जो पिछले दो वर्षों में काफी बेहतर रहा है, और यह अभी भी सुधार रहा है।

सामान्य रूप से, यहां एक पैटर्न जिसे मैंने बहुत उपयोगी पाया है, सार तत्वों के संदर्भ में इंटरफेस को परिभाषित करना और यथासंभव विधि हस्ताक्षर को ढीला करना है। यदि प्रेषण प्रतिबंध आवश्यक नहीं हैं, तो आप किसी भी प्रकार की अनुमति दे सकते हैं और बस बतख-टाइपिंग पर दुबला हो सकते हैं।यदि आप जूलिया को बताते हैं कि इसे कैसे हटाया जाना चाहिए या अपने आंतरिक कार्यान्वयन पर झुकाव करते समय केवल विशिष्ट पत्ते के प्रकारों को प्रेषण प्रतिबंधित करना है, तो आपका काम अधिक एक्स्टेंसिबल और पुनः उपयोग करने योग्य हो जाता है।

+0

यहां बहुत सारे अच्छे सुझाव हैं; मैं थोड़ा सा झुकाऊंगा और वापस रिपोर्ट करूंगा। धन्यवाद! – Philip

+0

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

+0

हां, यह [बतख टाइपिंग] है (http://stackoverflow.com/questions/4205130/what-is-duck-typing)। यह वास्तव में त्रुटि को एक स्तर से नीचे ले जाता है - 'sum (:: MyNamedArray) 'के लिए MethodError को फेंकने के बजाय, आपको एक विधि त्रुटि मिलती है जब यह योग के कार्यान्वयन के भीतर आपके सरणी में पुनरावृत्ति या अनुक्रमणिका करने का प्रयास करती है। यह एक रनटाइम गायब विधि त्रुटि किसी भी तरह से है। –

संबंधित मुद्दे