2010-12-31 13 views
14

मैं अपने कार्यक्रम मेंलागू रूपांतरण, आयात आवश्यक है या नहीं?

object MyString { 
    implicit def stringToMyString(s: String) = new MyString(s)  
} 

class MyString(str: String) { 
    def camelize = str.split("_").map(_.capitalize).mkString 

    override def toString = str 
} 


object Parse { 
    def main(args: Array[String]) { 
    val x = "active_record".camelize 
    // ... 
    } 
} 

लिखें। यह संकलन त्रुटि का कारण बनता है।

import MyString.stringToMyString 

फिर यह काम करता है।

ओडर्सकी के स्कैला में प्रोग्रामिंग मुझे स्रोत के साथी ऑब्जेक्ट में अपेक्षित रूपांतरण या अपेक्षित लक्ष्य प्रकारों को आयात करने की आवश्यकता नहीं है।

उत्तर

16

सहयोगी स्रोत में अपेक्षित रूपांतरण या अपेक्षित लक्ष्य प्रकारहोने की आवश्यकता नहीं हैआयात किया गया।

पर्याप्त सच है। अब, camelize विधि MyString पर परिभाषित की गई है, और, वास्तव में, इसके ऑब्जेक्ट साथी के अंदर MyString पर एक निहित रूपांतरण है। हालांकि, कोड में कुछ भी नहीं है जो संकलक को बताता है कि MyString लक्ष्य प्रकार अपेक्षित है।

, तो इसके बजाय आप इस लिखा है:

val x = ("active_record": MyString).camelize 

तो यह काम करेगा, क्योंकि संकलक पता होगा आप"active_record" एक MyString होने की उम्मीद , यह वस्तु MyString अंदर निहित रूपांतरण को देखने बना रही है।

यह थोड़ा सा प्रतिबंधक लग सकता है, लेकिन यह वास्तव में कई स्थानों पर काम करता है।कहते हैं, उदाहरण के लिए, आप के लिए किया था:

class Fraction(num: Int, denom: Int) { 
    ... 
    def +(b: Fraction) = ... 
    ... 
} 

और फिर आप इस तरह एक कोड था:

val x: Fraction = ... 
val y = x + 5 

अब, x करता है एक + विधि, जिसका उम्मीद प्रकारFraction है। तो संकलक Int से Fraction पर ऑब्जेक्ट Fraction (और ऑब्जेक्ट Int के अंदर, यदि कोई था, तो स्रोत स्रोत के बाद) के निहित रूपांतरण के लिए, यहां देखेंगे।

13

इस स्थिति में आपको आयात की आवश्यकता है क्योंकि संकलक यह नहीं जानता कि आपने camelize विधि को कहाँ से खींचा है। ,

object Parse { 
    def foo(s: MyString) = s.camelize 

    def main(args: Array[String]) { 
    val x = foo("active_record") 
    println(x.toString) 
    } 
} 

देखें Pimp my library pattern पर Martin's article आधारित: तो आप कर सकते हैं

ध्यान दें कि यह संभव शीर्ष स्तर पर defs डाल करने के लिए नहीं है, 'अगर प्रकार स्पष्ट है, यह आयात के बिना संकलित कर देगा वैश्विक दायरे के साथ एक अंतर्निहित रूपांतरण परिभाषित नहीं है। समाधान, एक वस्तु के अंदर डीईएफ़ जगह, और फिर इसे आयात करने के लिए है अर्थात्

object Implicits { 
    implicit def listExtensions[A](xs : List[A]) = new ListExtensions(xs) 
} 

और फिर प्रत्येक स्रोत फ़ाइल के शीर्ष पर, अपने अन्य आयात के साथ:

import Implicits._ 
+1

आईआईआरसी आप आयात ऑब्जेक्ट में पैकेज डाल सकते हैं, इसे कम से कम "वैश्विक" बना सकते हैं :-) – Landei

0

मैं स्काला पुस्तक में प्रोग्रामिंग में वाजिब वर्ग उदाहरण की कोशिश की, उसके साथी वस्तु में एक अंतर्निहित विधि डाल:

object Rational { 
    implicit def intToRational(num: Int) = 
    new Rational(num) 
} 

लेकिन कोड

2 + new Rational(1, 2) 

काम नहीं करता। रूपांतरण होने के लिए, एकल पहचानकर्ता नियम लागू होता है, यानी, आपको स्पष्ट विधि को दायरे में आयात करने की आवश्यकता होती है, भले ही इसे साथी ऑब्जेक्ट में परिभाषित किया गया हो।

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