2012-08-07 17 views
11

मैं एक प्रकार पैरामीटर के बजाय एक अमूर्त प्रकार का उपयोग करना चाहता हूं।स्कैला क्लास कन्स्ट्रक्टर और अमूर्त प्रकार

मेरी सामान्य वर्गों निर्माता में, मैं सामान्य प्रकार का एक पैरामीटर चाहते हैं, लेकिन कोड संकलन नहीं करता है:

class SomeOtherClass(val s: S){ 
    type S 
} 

स्केला संकलक त्रुटि है "नहीं मिला: प्रकार एस"

अगर मैं एक सार लिखने के बजाय एक प्रकार पैरामीटर का उपयोग, तो यह काम करता है:

class SomeClass[T](val t: T){ 
    //... 
} 

करता स्केला बल मुझे, एक अमूर्त प्रकार के बजाय एक प्रकार पैरामीटर का उपयोग करने के अगर मैं एक करना चाहते हैं कन्स्ट्रक्टर में जेनेरिक पैरामीटर?

क्या ऐसा करने का कोई और तरीका है?

उत्तर

3

आप उस मामले में जेनेरिक प्रकार पैरामीटर का उपयोग करने के लिए काफी मजबूर हैं। आप कक्षा के बाहर के प्रकार को घोषित करके इसके आसपास काम कर सकते हैं, लेकिन फिर आपको रैपर को तुरंत चालू करना होगा और फिर ऑब्जेक्ट और यह बहुत बदसूरत हो जाएगा।

trait FooDef { 
    type T 
    class Foo(val x: T) 
} 
val ifd = new FooDef { type T = Int } 
val ifoo = new ifd.Foo(5) 
val sfd = new FooDef { type T = String } 
val sfoo = new sfd.Foo("hi") 
def intFoos(f: fd.Foo forSome { val fd: FooDef {type T = Int} }) = f.x + 1 
0

कंपाइलर को यह कैसे पता होना चाहिए कि इसका उपयोग किस प्रकार करना चाहिए? या तो आपको सीधे प्रकार निर्दिष्ट करना होगा, जो अधिक समझ में नहीं आता है, या सामान्य का उपयोग नहीं करेगा। इसे काम करने का एक तरीका है, लेकिन मुझे नहीं लगता कि इससे आपकी मदद मिलेगी।

class SomeClass(s: SomeClass#S) { 
    type S 
} 

लेकिन जैसा कि कुछ क्लास # एस परिभाषित नहीं किया गया है, इसका कोई उदाहरण नहीं है।

+0

मजेदार पर्याप्त यह आपको उदाहरण 'नए SomeClass (5.asInstanceOf [SomeClass # S]) {प्रकार एस = Int}' बनाने की अनुमति देगा। ध्यान दें कि कोई सुरक्षा नहीं है, एस अभी भी कलाकारों में अनिर्धारित है। – Kaito

+0

तो मूल रूप से इसे सही करने के लिए, मुझे अन्य दो उत्तरों को देखने की ज़रूरत है? –

+0

@AntKutschera हां। – Nicolas

0

शायद आप ऐसा कुछ चाहते हैं? इस तरह आप AbstractFooFactory के कई उदाहरण Foo एस के उत्पादन के लिए अलग-अलग उदाहरण प्राप्त कर सकते हैं।

trait AbstractFooFactory { 
    type S 
    def makeFoo(s:S):Foo 
    class Foo(val s:S) {} 
} 

object StringFooFactory extends AbstractFooFactory { 
    override type S = String 
    override def makeFoo(s:String) = new Foo(s) 
} 

val b = StringFooFactory.makeFoo("bar") 
val s:String = b.s 
1

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

abstract class SomeOtherClass { 
    type S 
    val s: S 
} 
उपयोग-स्थल पर

तब:

val x = new SomeOtherClass { 
    type S = String 
    val s = "abc" 
} 

पैरामीटर के बिना, यहाँ सार वर्ग एक विशेषता के बराबर है। आप एक विशेषता का उपयोग बंद कर रहे हैं क्योंकि यह कम प्रतिबंधक है (आप केवल एक बेस क्लास का विस्तार कर सकते हैं)।

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