समस्या प्रोटोकॉल के साथ प्रोटोकॉल द्वारा बाधित एक सामान्य प्लेसहोल्डर को भ्रमित करने के साथ निहित है। यहां एक सरल उदाहरण है, अपने कोड के समान, इसे साफ़ करने और इसे साफ़ करने के लिए:
// first, define a protocol and two structs that conform to it
protocol P { }
struct S1: P { }
struct S2: P { }
// now, a function that returns an object in the form
// of a reference to protocol P
func f() -> P {
// S1 conforms to P so that’s fine
return S1()
}
// ok all well and good, this works fine:
let obj = f()
// now, to do something similar to your example code,
// declare a generic function that returns a generic
// placeholder that is _constrained_ by P
// This will NOT compile:
func g<T: P>() -> T { return S1() }
यह संकलित क्यों नहीं करता है?
तरह से सामान्य कार्यों काम है कि संकलन समय, जब आप फ़ंक्शन को कॉल करें, संकलक क्या प्लेसहोल्डर T
होने की जरूरत है टाइप का फैसला करता है, और फिर आप T
की सभी घटनाओं की है कि प्रकार के साथ बदल के साथ एक समारोह में लिखते हैं पर ।
नीचे दिए गए उदाहरण के साथ तो, T
S1
द्वारा प्रतिस्थापित किया जाना चाहिए:
let obj1: S1 = g()
// because T needs to be S1, the generic function g above is
// rewritten by the compiler like this:
func g() -> S1 { return S1() }
यह ठीक लग रहा है। सिवाय, अगर हम T
S2
के लिए चाहते थे तो क्या होगा? S2
P
के अनुरूप है इसलिए T
के लिए एक पूरी तरह से वैध मूल्य है। लेकिन यह कैसे काम कर सकता है:
// require our result to be of type S2
let obj2: S2 = g()
// so T gets replaced with S2… but now we see the problem.
// you can’t return S1 from a function that has a return type of S2.
// this would result in a compilation error that S2 is not
// convertible to S1
func g() -> S2 { return S1() }
यहां आपको प्राप्त होने वाले त्रुटि संदेश की उत्पत्ति है। आपका प्लेसहोल्डर A
किसी भी प्रकार कि Protocol
के अनुरूप है के लिए में खड़े हो सकते हैं, लेकिन आप एक विशिष्ट प्रकार (AClass
) है कि प्रोटोकॉल के अनुरूप वापस जाने के लिए कोशिश कर रहे हैं। तो यह आपको ऐसा करने नहीं देगा।
स्रोत
2015-03-14 12:24:54
आप _generic_ प्रकार 'ValueType' वाले प्रोटोकॉल की घोषणा करते हैं। फिर, प्रोटोकॉल के अनुरूप होने के लिए, किसी के पास 'ValueType == स्ट्रिंग' होना चाहिए। इस प्रकार 'ValueType' का उद्देश्य _generic_ होना नहीं है। ध्यान दें कि 'स्ट्रिंग' प्रोटोकॉल नहीं है, बल्कि एक ठोस प्रकार है। –