2010-11-29 21 views
8

विस्तारित करना मुझे एक सीलबंद विशेषता है जिसमें एक घोषित विधि है जो वास्तविक वर्ग को प्राप्त करती है जो विशेषता को बढ़ाती है। क्या मुझे एक अमूर्त प्रकार, पैरामीटर प्रकार या का उपयोग करना चाहिए, इसे हल करने का कोई और अच्छा तरीका है?एक विशेषता और प्रकार

sealed trait Foo { 
    type T 
    def doit(other: T): T 
} 

या

sealed trait Foo[T] { 
    def doit(other: T): T 
} 

ध्यान दें कि T इस उदाहरण में Foo की एक उप-प्रकार होना चाहिए। अगर मैं इस तरह यह करने के प्रकार जानकारी भी दोहराया महसूस करता है:

case class Bar(name: String) extends Foo[Bar] { 
    def doit(other: Bar): Bar = ... 
} 

उत्तर

2

आप पुनरावृत्ति में कटौती कर सकते हैं कुछ हद तक अपने doit विधि एक कारखाने समारोह वापसी होने से:

trait Foo[T] { 
    self: T => 
    def doit: T => T 
} 

case class Bar(name: String) extends Foo[Bar] { 
    // note: types omitted 
    def doit = { other => Bar(name + other.name) } 
} 

यह एक सार प्रकार के साथ भी ऐसा ही करने के लिए संभव नहीं है:

trait Foo { 
    self: T => // won't compile because T isn't defined yet 
    type T 
    def doit: T => T 
} 
1

संपादित - नीचे अपने मूल जवाब है। आपकी टिप्पणी इंगित करती है कि आप मिलान करने वाले प्रकार के मनमाना उदाहरण को वापस करना चाहते हैं, लेकिन मुझे सच में विश्वास नहीं है कि यह किसी भी तरह से समझदार है। मान लीजिए यह थे, T.type वाक्य रचना के माध्यम से:

trait T { def foo : T.type } 

trait U extends T { def foo = new U } //must be a U 

class W extends U 

val w : W = (new W).foo //oh dear. 

यह accomplishable है के माध्यम से this.type:

scala> trait T { 
| def foo : this.type 
| } 
defined trait T 

scala> class W extends T { 
| def foo = this 
| } 
defined class W 

scala> (new W).foo 
res0: W = [email protected] 

scala> res0.foo 
res1: res0.type = [email protected] 

और फिर भी:

scala> ((new W) : T) 
res4: T = [email protected] 

scala> res4.foo.foo.foo 
res5: res4.type = [email protected] 
+0

परिचित लग रहा है। क्या आप शायद इसका उदाहरण दे सकते हैं? – chrsan

+0

अगर मैं एक ही प्रकार का एक नया उदाहरण वापस करना चाहता हूं तो यह काम नहीं कर रहा है? – chrsan

+0

हां - 'this.type' पथ-निर्भर है: यह केवल वर्तमान उदाहरण –

4

वे ज्यादातर परस्पर विनिमय कर रहे। ओडर्स्की के अनुसार, कारण मुख्य रूप से पूर्णता के लिए था: इसी तथ्य के समान कि विधियों और क्षेत्रों (मूल्य) या तो अमूर्त या पैरामीटर के रूप में पारित हो सकते हैं, इसलिए प्रकार हो सकते हैं।

जब आप एक ही प्रकार के नाम का उपयोग करते हैं तो कई गुणों को मिश्रित करना चाहते हैं, तो एक अमूर्त प्रकार का उपयोग करना बेहतर होता है। http://www.artima.com/weblogs/viewpost.jsp?thread=270195

1
trait Foo[A <: Foo[A]] 

यह विशेषता केवल में मिलाया जा सकता है अगर एक फू के एक उप-प्रकार है [एक] और: प्रकार पैरामीटर के साथ आप स्पष्ट रूप से यहाँ एक लेख यह सब समझा है प्रत्येक

के प्रकार उत्तीर्ण करने की आवश्यकता एकमात्र प्रकार संतोषजनक है कि वर्ग फू को मिश्रित किया जा रहा है। मैंने लिफ्ट में मैपर लक्षणों में यह समाधान देखा।

+0

वापस करने के लिए मान्य है।'कक्षा बार फू [बार]' और 'कक्षा बाज़ फैलाता है' फू [बार] 'का विस्तार करें। –

2

आप लिख सकते हैं:

trait Foo[T] { 
    self:T => 
    def doit(other: T): T 
} 

case class Bar(name: String) extends Foo[Bar] { 
    def doit(other: Bar): Bar = ... 
} 

अपने उदाहरण के अंतर यह है कि बार किसी अन्य तरीके से (जैसे case class Bar(name: String) extends Foo[String]) में instantiated नहीं किया जा सकता है।

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