2012-02-07 23 views
25

द्वारा कक्षा का साथी ऑब्जेक्ट प्राप्त करें जो मैं करने की कोशिश कर रहा हूं वह एक ऐसा कार्य करना है जो सामान्य वर्ग ले ले और इसमें एक स्थिर विधि का उपयोग करे (जावा भाषा के लिए खेद है, मेरा मतलब है कि इसके साथी ऑब्जेक्ट का तरीका)।सामान्य जेनेरिक प्रकार स्काला

trait Worker {def doSth: Unit} 

class Base 

object Base extends Worker 

// this actually wouldn't work, just to show what I'm trying to achieve 
def callSthStatic[T that companion object is <: Worker](implicit m: Manifest[T]) { 
    // here I want to call T.doSth (on T object) 
    m.getMagicallyCompanionObject.doSth 
} 

कोई विचार? यदि स्काला 2.9.x. का उपयोग कर

trait Companion[T] { 
    type C 
    def apply() : C 
} 

object Companion { 
    implicit def companion[T](implicit comp : Companion[T]) = comp() 
} 

object TestCompanion { 
    trait Foo 

    object Foo { 
    def bar = "wibble" 

    // Per-companion boilerplate for access via implicit resolution 
    implicit def companion = new Companion[Foo] { 
     type C = Foo.type 
     def apply() = Foo 
    } 
    } 

    import Companion._ 

    val fc = companion[Foo] // Type is Foo.type 
    val s = fc.bar   // bar is accessible 
} 

यह -Ydependent-method-types ध्वज के साथ संकलित किया जाना चाहिए:

उत्तर

20

A gist by Miles Sabin आप एक संकेत दे सकता है

+0

मैंने वास्तविक जिस्ट सामग्री को जोड़ा - गस्ट गायब हो सकता है और अकेले लिंक एक टिप्पणी के रूप में योग्यता प्राप्त करता है। –

+0

मुझे "त्रुटि मिल रही है: अवैध आश्रित विधि प्रकार निहित डीफ़ साथी [टी] (अंतर्निहित COMP: सहयोगी [टी]) = comp.apply()" लाइन पर "निहित डीफ़ साथी [टी] (अंतर्निहित COMP: सहयोगी [ टी]) = comp() "स्कैला 2.9.1 के साथ। क्या मैं इसे गलत कर रहा हूँ? :-) –

+3

मैं मूल रूप से जोड़ दूंगा कि यदि 'फू' प्रकार दिखाई देता है तो यह साथी वस्तु है, इसलिए यह काफी निफ्टी दिखता है, मुझे नहीं लगता कि यह अभ्यास में उपयोगी है। –

7

आप साथी वर्ग और उसके उदाहरण को प्राप्त करने के लिए प्रतिबिंब का उपयोग कर सकते हैं, लेकिन यह स्कैला आंतरिक पर निर्भर करता है जो कुछ दूर (?) भविष्य में बदल सकता है। और कोई भी सुरक्षा नहीं है क्योंकि आपको AnyRef मिलता है। लेकिन आपकी कक्षाओं और वस्तुओं में कोई भी प्रभाव जोड़ने की आवश्यकता नहीं है।

def companionOf[T : Manifest] : Option[AnyRef] = try{ 
    val classOfT = implicitly[Manifest[T]].erasure 
    val companionClassName = classOfT.getName + "$" 
    val companionClass = Class.forName(companionClassName) 
    val moduleField = companionClass.getField("MODULE$") 
    Some(moduleField.get(null)) 
} catch { 
    case e => None 
} 

case class A(i : Int) 

companionOf[A].collect{case a : A.type => a(1)} 
// res1: Option[A] = Some(A(1)) 
+0

धन्यवाद, प्रतिबिंब समस्या को हल करेगा ... स्कैला संस्करण अद्यतन तक, साथी ऑब्जेक्ट के नाम को इस तरह से रखने का वादा नहीं किया जाता है। –

+1

अच्छा, यह सच है। लेकिन मुझे नहीं लगता कि नामकरण जल्द ही बदल जाएगा, क्योंकि यह सम्मेलन कम से कम 2.8 दिनों के शुरुआती दिनों से कम रहा। – MxFr

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