2013-12-14 4 views
9

यह अच्छी तरह सेनहीं ClassTag MyClass.this.T के लिए उपलब्ध

class MyClass[T<: Actor: ClassTag] extends Actor { 
    //.... 
} 

काम करता है लेकिन इस त्रुटि No ClassTag available for MyClass.this.T

class MyClass extends Actor { 
    type T<: Actor 
    //... 
} 

भी जब निम्न कार्य की वजह से नहीं करता है:

class MyClass extends Actor { 
    type T<: Actor: ClassTag //this doesn't even compile 
    //... 
} 

मैं एक सार type का उपयोग कैसे करूं और त्रुटि से छुटकारा पा सकता हूं?

उत्तर

8
class M[A <: B: C] 

class M[A <: B](implicit c: C[A]) 

इसलिए के लिए कम है, यदि आप एक सार प्रकार सदस्य को A ले जाते हैं, आप की तरह

abstract class M { 
    type A <: B 
    implicit protected def c: C[A] 
} 

कुछ लिख सकते हैं और उपलब्ध कराने के लिए M को लागू किसी को भी आवश्यकता होती है करने के लिए होगा ऐसे मूल्यc। आप M गैर सार चाहते हैं, आप

संपादित टिप्पणियों का जवाब देने के प्रकार C[A], जो बदले में उस प्रकार A का मतलब निर्माता प्रकार पैरामीटर होना चाहिए की एक निर्माता value पैरामीटर की आवश्यकता होती है चाहिए ...


: नोटेशन A : C को C[A] के एक अंतर्निहित मान पैरामीटर में विस्तार के रूप में परिभाषित किया गया है। C को संदर्भ बाध्य कहा जाता है, और इसे A टाइप करने के लिए टाइप प्रकार C[_] के लिए पूछने के रूप में समझा जा सकता है। यदि आप M लागू करते हैं तो आपको implicit संशोधक को दोहराने की आवश्यकता नहीं है। यह वहाँ क्यों है? मैं आपको एक उदाहरण एक प्रसिद्ध प्रकार वर्ग Ordering का उपयोग कर देता हूँ:

abstract class Foo { 
    type A 
    implicit protected def ord: Ordering[A] 

    protected def seq: Seq[A] 

    def range: (A, A) = { 
    val xs = seq 
    xs.min -> xs.max 
    } 
} 

आप implicit हटा दिया है, तो आप xs.min और xs.max जो एक अंतर्निहित Ordering की आवश्यकता के लिए कॉल परिवर्तन होगा।

object Bar extends Foo { 
    type A = Int 
    val seq = List(8, 34, 5, 21, 3, 13) 
    val ord = Ordering.Int // don't need to repeat `implicit` 
} 

Bar.range // (3, 34) 

यहाँ, Bar दिखाता है कि आप अंतर्निहित मूल्य पैरामीटर प्रदान करते हैं। यह ClassTag के लिए एक ही होगा:

trait MyClass { 
    type A 
    implicit def tag: reflect.ClassTag[A] 
} 

object StringClass extends MyClass { 
    type A = String 
    // type String is statically known, thus compiler gives us this: 
    val tag = reflect.classTag[String] 
} 

अपने बच्चे को कक्षा सामान्य फिर, आप एक वर्ग टैग प्रदान करने के लिए जिम्मेदारी पर पारित करने के लिए की आवश्यकता होगी है:

class GenericClass[A1](implicit val tag: reflect.ClassTag[A1]) { 
    type A = A1 
} 
+0

दिलचस्प। मैंने इसके साथ थोड़ा सा खेला, और दो सवाल उठ गए: 1) 'एम' * विधि * में विधि 'c' क्यों है? Parametrized प्रकारों का उपयोग कर पिछले दो संस्करणों के बराबर एक गैर-अंतर्निहित विधि नहीं है? 2) 'क्लासटाग' के विशेष मामले में एक कन्स्ट्रक्टर वैल्यू की आवश्यकता नहीं है (मैंने इसे कक्षा में 'ओवरराइड वैल सी = क्लासटाग [...] 'के साथ बदल दिया है। क्या यह आम तौर पर संभव नहीं है? – Beryllium

+0

मैं बाल कक्षाओं में 'सी: क्लासटाग 'के कार्यान्वयन को कैसे प्रदान करूं? यह कैसा दिखना चाहिए? –

+0

ऐसा लगता है कि ऑब्जेक्ट स्ट्रिंग क्लास में अनावश्यक पुनरावृत्ति है MyClass' - प्रकार ए = 'स्ट्रिंग' और वैल टैग = reflect.classTag [' स्ट्रिंग'] बढ़ाता है? क्या मैं इससे बच सकता हूं? –

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