शुरुआत के लिए, की त्रुटि स्पष्ट करता हूं:
को देखते हुए:
class Foo<T:Hashable> { }
class SubFoo<String> : Foo<String> { }
यहाँ भ्रामक बात यह है कि हम उम्मीद करते हैं "स्ट्रिंग" स्विफ्ट परिभाषित संरचना जो पात्रों का एक संग्रह रखती है मतलब है। लेकिन ऐसा नहीं है।
यहां, "स्ट्रिंग" सामान्य प्रकार का नाम है जिसे हमने अपना नया सबक्लास, SubFoo
दिया है।
class SubFoo<String> : Foo<T> { }
यह पंक्ति एक अघोषित प्रकार के उपयोग के रूप T
के लिए एक त्रुटि उत्पन्न करता है: यदि हम कुछ बदलाव करने यह बहुत स्पष्ट हो जाता है।
तो अगर हम इस के लिए लाइन बदलने के लिए:
class SubFoo<T> : Foo<T> { }
हम वापस वही त्रुटि आप मूल रूप से किया था करने के लिए कर रहे हैं, 'टी' 'Hashable' के अनुरूप नहीं है। यह यहां स्पष्ट है, क्योंकि टी भ्रमित रूप से मौजूदा स्विफ्ट प्रकार का नाम नहीं है जो 'हैशबल' के अनुरूप होता है। यह स्पष्ट है 'टी' एक सामान्य है।
जब हम 'स्ट्रिंग' लिखते हैं, तो यह सामान्य प्रकार के प्लेसहोल्डर नाम भी है, और वास्तव में String
प्रकार स्विफ्ट में मौजूद नहीं है।
हम एक सामान्य वर्ग की एक विशिष्ट प्रकार के लिए एक अलग नाम चाहते हैं, उचित दृष्टिकोण लगभग निश्चित रूप से एक typealias
है:
class Foo<T:Hashable> {
}
typealias StringFoo = Foo<String>
यह पूरी तरह से वैध है स्विफ्ट, और यह सिर्फ ठीक संकलित करता है।
है कि हम क्या चाहते हैं वास्तव में उपवर्ग और एक सामान्य वर्ग के लिए तरीकों या गुण जोड़ने के लिए है, तो इसके बजाय, तो हम क्या जरूरत है एक वर्ग या प्रोटोकॉल है कि हमारे सामान्य अधिक हम क्या जरूरत के लिए विशिष्ट बना देगा।
मूल समस्या के लिए वापस जा रहे हैं, की पहली त्रुटि से छुटकारा पाने करते हैं:
class Foo<T: Hashable>
class SubFoo<T: Hashable> : Foo<T> { }
यह पूरी तरह से वैध स्विफ्ट है। लेकिन यह हम जो कर रहे हैं उसके लिए यह विशेष रूप से उपयोगी नहीं हो सकता है।
केवल कारण है कि हम निम्न कार्य नहीं कर सकते हैं: क्योंकि String
एक स्विफ्ट वर्ग नहीं है
class SubFoo<T: String> : Foo<T> { }
बस है - यह एक संरचना है। और किसी भी संरचना के लिए इसकी अनुमति नहीं है।
हम एक नए प्रोटोकॉल कि Hashable
से विरासत लिखते हैं, हम उस का उपयोग कर सकते हैं:
protocol MyProtocol : Hashable { }
class Foo<T: Hashable> { }
class SubFoo<T: MyProtocol> : Foo<T> { }
यह पूरी तरह से वैध है।
ही, ध्यान दें कि हम वास्तव में Hashable
से विरासत की जरूरत नहीं है कि:
protocol MyProtocol { }
class Foo<T: Hashable> { }
class SubFoo<T: Hashable, MyProtocol> { }
यह भी पूरी तरह से वैध है।
हालांकि, ध्यान दें कि, किसी भी कारण से, स्विफ्ट आपको यहां कक्षा का उपयोग करने नहीं देगा। उदाहरण के लिए:
class MyClass : Hashable { }
class Foo<T: Hashable> { }
class SubFoo<T: MyClass> : Foo<T> { }
स्विफ्ट रहस्यमय तरीके से शिकायत है कि 'टी' 'Hashable' (यहां तक कि जब हम आवश्यक कोड जोड़ने यह इतना बनाने के लिए के अनुरूप नहीं है
अंत में, सही। दृष्टिकोण, और सबसे स्विफ्ट-उपयुक्त दृष्टिकोण 'हैशबल' से प्राप्त एक नया प्रोटोकॉल लिखने जा रहा है और आपको जो भी कार्यक्षमता चाहिए उसे जोड़ता है।
यह सख्ती से महत्वपूर्ण नहीं होना चाहिए कि हमारा सबक्लास String
स्वीकार करता है। यह महत्वपूर्ण होना चाहिए कि wha हमारे सबक्लास लेता है, इसमें आवश्यक विधियां और गुण होते हैं जिन्हें हम जो कुछ भी कर रहे हैं उसके लिए हमें चाहिए।
ऐसा नहीं है। इसके बारे में एक स्विफ्ट मुद्दा/सीमा है, http://stackoverflow.com/questions/24138359/limitation-with-classes-derived-from-generic-classes-in-swift – Ixx
@lxx: Ick देखें। मुझे संदेह है कि अभी भी * कारण * है, लेकिन आप एक अलग समाधान चाहते हैं। मैंने कोशिश करने के लिए एक संभावित समाधान के साथ अपना जवाब संपादित किया है। –
ठीक है, हां, फेंक प्रकार पैरामीटर के साथ समाधान काम करता है लेकिन मैंने कोशिश नहीं की क्योंकि यह बदसूरत है। दूसरी तरफ, मैंने फिर से टाइपियास समाधान की कोशिश की और यह अब काम करता है। एक मुद्दा था क्योंकि (चयनित उत्तर) यह Int को प्लेसहोल्डर के रूप में उपयोग करता है, यही कारण है कि मैंने स्ट्रिंग, पैरामीटर का उपयोग करने का प्रयास किया और यह त्रुटियों का कारण बन रहा था। मैंने इसे टी के साथ बदल दिया और टाइपलाइज़ को कक्षा घोषित कर दिया, यह संकलित नहीं है। हालांकि यह अभी भी एक कामकाज है। मुझे सही समाधान पर वापस इंगित करने के लिए धन्यवाद :) – Ixx