2012-09-01 15 views
5

इस कोड पर विचार करें:हो रही संदर्भ

trait A { 
    def a : Int 
} 

def f (a : Int) = { 
    def a0 = a 
    new A { 
    def a = a0 
    } 
} 
समस्या

काफी स्पष्ट है: def a0 = a एक ठेठ कष्टप्रद बॉयलरप्लेट कोड है और स्थिति केवल बिगड़ जाती है जब अधिक पैरामीटर प्राप्त की शुरुआत की।

मुझे आश्चर्य है कि किसी भी तरह से गुण के उदाहरण की घोषणा के अंदर बाहरी दायरे के a चर का प्रत्यक्ष संदर्भ प्राप्त करना संभव है और इस प्रकार इंटरमीडिएट a0 से छुटकारा पाने के लिए।

कृपया ध्यान रखें कि फ़ंक्शन को बदलने के रूप में फ़ंक्शन के इनपुट पैरामीटर के नाम बदलने की अनुमति नहीं है।

उत्तर

4

मैं, नहीं लगता है प्रत्यक्ष तरीका है कि ऐसा करने के लिए करते हैं क्योंकि यह कुछ विशेष (काल्पनिक) पहचानकर्ता thisMethod की आवश्यकता होगी। हालांकि, अपने संदर्भ के आधार पर निम्नलिखित दो नाम छाया से बचने के लिए तरीके संभव हो सकता है:

(1) को लागू करने वर्ग के साथ गुमनाम वर्ग A बदलें:

case class AImpl(a: Int) extends A 

def f(a : Int): A = AImpl(a) 

(2) एक सार में f को परिभाषित करें विशेषता और इसके लिए एक ठोस कार्यान्वयन का उपयोग करें: (अपने एपीआई बदले बिना)

trait F { 
    def f(a: Int): A 
} 

object FImpl extends F { 
    def f(a0: Int): A = new A { val a = a0 } 
} 

def test(factory: F): A = factory.f(a = 33) 
3

मैं निकटतम आप प्राप्त कर सकते हैं लगता है:

def f(a: Int) = { 
    def ff(a0: Int) = { 
    new A { 
     def a = a0 
    } 
    } 
    ff(a) 
} 

स्कैला में, विधियां प्रकार नहीं हैं। इस प्रकार, उन्हें टाइप सिस्टम या किसी भी सदस्य के साथ संदर्भित करना संभव नहीं है।

scala> class X{def f = 0} 
defined class X 

scala> import reflect.runtime.universe._ 
import reflect.runtime.universe._ 

scala> typeOf[X].member(newTermName("f")).isType 
res9: Boolean = false 
3

यहां एक अज्ञात समाधान है।

package eyeshadow 

trait A { 
    def a: Int 
} 

class B { 
    def f(a: Int) = { 
    val fa: A = new { 
     //private val b = a 
     private[this] val b = a // crashes, sorry scalac. edit: ok in 2.11 
    } with A { 
     def a = b 
    } 
    fa.a 
    /* 
    * This seems far-fetched, but compare the initial objections in 
    * https://issues.scala-lang.org/browse/SI-3836 
    * All I want is to alias a symbol, right? 
    * Maybe the override means "do not shadow." 
    val fa: A = new A { 
     //import fa.{ a => b } 
     import this.{ a => b } 
     override def b = a 
    } 
    */ 
    } 
} 

object Test { 
    def main(args: Array[String]) { 
    val b = new B 
    println(b f 7) 
    } 
} 
+0

धन्यवाद, अज्ञात अप-मतदाता। मैंने कभी भी आप पर विश्वास खो दिया नहीं है। लेकिन वास्तविक धन्यवाद उन लोगों के पास जाता है जो पागल प्रश्न पूछते हैं और अन्य लोग जो इतने तेज़ी से जवाब देते हैं कि जब तक मैं कुछ सोचता हूं, तो यह वास्तव में पागल होना चाहिए। –