2013-02-20 13 views
7

तो मैं twitter Scala school के माध्यम से स्कैला सीखने की कोशिश कर रहा हूं। लेकिन मैं वर्तमान में उनके type bound examples में से एक पर अटक गया हूं।स्कैला प्रकार बाध्य त्रुटि प्राप्त करना: नहीं मिला: प्रकार <% <

विशेष रूप से, यह वह जगह है जहां <%< टाइप-रिलेशन ऑपरेटर का उपयोग करके टाइप को एक निश्चित प्रकार के रूप में देखा जा सकता है।

जब मैं अपने स्काला कंसोल में निम्न कोड निष्पादित करें:

scala> class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value } 

... मैं निम्नलिखित त्रुटियाँ मिलती है:

<console>:7: error: not found: type <%< 
     class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value } 
                    ^
<console>:7: error: overloaded method value + with alternatives: 
    (x: Double)Double <and> 
    (x: Float)Float <and> 
    (x: Long)Long <and> 
    (x: Int)Int <and> 
    (x: Char)Int <and> 
    (x: Short)Int <and> 
    (x: Byte)Int <and> 
    (x: String)String 
cannot be applied to (A) 
     class Container[A](value: A) { def addIt(implicit evidence: A <%< Int) = 123 + value } 

मेरा प्रश्न है, क्यों स्काला दुभाषिया शिकायत कर रहा है है?

मैं स्कैला दस्तावेज को देखने की कोशिश कर रहा हूं लेकिन मैं कहीं भी ऑपरेटर को जानकारी नहीं ढूंढ पा रहा हूं। मैं देख सकता हूं कि स्कैला स्कूल स्कैला 2.8.0 के आधार पर बनाया गया था, और मैं स्कैला 2.10.0 चला रहा हूं - तो शायद इसे हटा दिया गया है? यदि ऐसा है, तो यह एक उपयोगी ऑपरेटर की तरह क्यों लगता है?

+2

ऐसा लगता है कि यह स्कैला 2.10 में नहीं है, हालांकि मुझे यकीन नहीं है कि क्यों - https://github.com/scala/scala/blob/v2.10.0/src/library/scala/Predef.scala # एल 1 – Impredicative

+4

को https://github.com/scala/scala/commit/e1780e9686914d835b295e125511368eeb1d0733#L0L350 – Debilski

+1

में बहिष्कृत किया गया था ठीक है! ऐसा लगता है कि मैंने नीचे अनुमान लगाया है। – Impredicative

उत्तर

6

बाधा A <%< B स्काला 2.8 में तो तुम हमेशा इसे वापस कि जिस तरह से ला सकता है के रूप में

sealed abstract class <%<[-From, +To] extends (From => To) 
    object <%< { 
    implicit def conformsOrViewsAs[A <% B, B]: A <%< B = new (A <%< B) {def apply(x: A) = x} 
    } 

परिभाषित किया गया है। हालांकि, मेरा अनुमान है कि कारण यह पदावनत है कि एक दृश्य के लिए बाध्य सिर्फ A से B को एक अंतर्निहित समारोह लिए पूछ रहा है, और वहाँ पहले से ही एक सामान्यीकृत तरह से है कि विशेष बाधा व्यक्त करने के लिए एक पूरी तरह से अच्छा तरीका है यह है कि:

class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value } 

एक तरफ के रूप में, यह ध्यान देने योग्य है कि यह ऑपरेटर नहीं है, लेकिन इन्फिक्स स्थिति में एक वर्ग जैसा कि आप परिभाषा से देख सकते हैं। => के लिए भी यही सच है, जो Function1 प्रकार कन्स्ट्रक्टर का संदर्भ देने का एक और तरीका है।

+1

मैं वर्ग को हटाने के पीछे एक आधिकारिक तर्क के लिए थोड़ा सा खोज रहा हूं, लेकिन बिना किसी किस्मत के। आपका अनुमान किसी के जैसा अच्छा है और मेरी जिज्ञासा को पूरा करने के लिए पर्याप्त है, धन्यवाद! :) – jpihl

2

this site पर, यह कहता है कि A <%< B स्कैला 2.9 में बहिष्कृत हो गया। मुझे नहीं पता क्यों, और मैं मानता हूं कि यह थोड़ा अजीब लगता है क्योंकि यह मेरे लिए एक बहुत ही उपयोगी ऑपरेटर जैसा दिखता है।

+2

जैसा कि https://github.com/scala/scala/commit/e1780e9686914d835b295e125511368eeb1d0733#L0L350 पर गिटहब परिवर्तन पर वर्णित है, 'ए => बी' का उपयोग 'ए <% <बी' के स्थान पर किया जाना चाहिए क्योंकि उनके पास वही अर्थशास्त्र। –

-1

सही उपयोग,

class Container[A](value: A) { def addIt[A <% Int] = 123 + value } 

अतिभारित मूल्यों के लिए के रूप में हो रहा है scala अस्पष्टता को हल करने के लिए नहीं चुनने है; इस मामले में, आपको फैसला करना होगा।

  • आप के साथ डिबगिंग की कोशिश कर सकते हैं: -Xprint:typer

  • या आप तय कर सकते कि A या तो class Container[A](value: A) { def addIt = 123 + value.asInstanceOf[Int] } का उपयोग कर या पहले से ही class Container[A](value: A) { def addIt(implicit evidence: A => Int) = 123 + value } सुझाव दिया द्वारा वास्तव में Int है। वे बराबर हैं। लेकिन यहां आप कह रहे हैं कि AInt का एक प्रकार है; A के विपरीत Int के रूप में देखा जा सकता है जो <% करता है।

वह दूसरा विकल्प छोटा नहीं है।पर विचार करें निम्नलिखित

scala> class Container[A](value: A) { def printIt[A <% Int] = println(123+" could be " + value) } 
defined class Container 

scala> val x = new Container("Love") 
x: Container[String] = [email protected] 

scala> x.printIt 
123 could be Love 

जाहिर "love"Int का एक प्रकार है, क्योंकि यह String है, फिर भी यह इस संदर्भ में पूरी तरह से ठीक है नहीं है: यही कारण है कि आप A => Int उपयोग के बारे में सावधान रहना चाहिए।

+0

शीर्ष पर स्निपेट सबसे निश्चित रूप से सही उपयोग नहीं है! 'AddIt' विधि पर टाइप पैरामीटर 'ए' कक्षा पर पैरामीटर' ए 'को छायांकन कर रहा है, इसलिए इस स्थिति में कुछ भी नहीं जोड़ा गया है। – Impredicative

+0

आपका दूसरा उदाहरण केवल वैश्विक अंतर्निहित 'any2stringAdd' के कारण काम करता है जो किसी भी प्रकार को इसे संयोजित करने के प्रयोजनों के लिए स्ट्रिंग में परिवर्तित करने देता है - जो इस प्रश्न के लिए पूरी तरह सह-आकस्मिक है। साथ ही, यह कहना सही नहीं है कि '{def addIt = 123 + value.asInstanceOf [int]}' और '{def addIt (अंतर्निहित सबूत: ए => Int) = 123 + value}' समकक्ष हैं। एक असुरक्षित कलाकार है जो किसी भी चीज के लिए संकलन समय पर उड़ाएगा जो Int के उप-प्रकार नहीं है। दूसरा टाइप-सुरक्षित है, जो एक निहित रूपांतरण पर निर्भर करता है। – Impredicative

+0

क्षमा करें, रन समय पर उड़ाएं, समय संकलित नहीं करें। – Impredicative

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