Scala Language
प्रकार का आविष्कार
खोज…
स्थानीय प्रकार का आविष्कार
स्काला में भाषा के लिए एक शक्तिशाली टाइप-इनफेरेंस मैकेनिज्म अंतर्निहित है। इस तंत्र को 'स्थानीय प्रकार का आविष्कार' कहा जाता है:
val i = 1 + 2 // the type of i is Int
val s = "I am a String" // the type of s is String
def squared(x : Int) = x*x // the return type of squared is Int
कंपाइलर इनिशियलाइज़ेशन एक्सप्रेशन से वेरिएबल्स के प्रकार का अनुमान लगा सकता है। इसी तरह, वापसी प्रकार की विधियों को छोड़ा जा सकता है, क्योंकि वे विधि बॉडी द्वारा लौटाए गए प्रकार के बराबर हैं। उपरोक्त उदाहरण नीचे, स्पष्ट प्रकार की घोषणाओं के बराबर हैं:
val i: Int = 1 + 2
val s: String = "I am a String"
def squared(x : Int): Int = x*x
प्रकार आविष्कार और पीढ़ी
जब पॉलिमॉर्फिक तरीके कहे जाते हैं, या जब जेनेरिक कक्षाएं तुरंत शुरू की जाती हैं, तो स्काला कंपाइलर टाइप पैरामीटर भी घटा सकता है:
case class InferedPair[A, B](a: A, b: B)
val pairFirstInst = InferedPair("Husband", "Wife") //type is InferedPair[String, String]
// Equivalent, with type explicitly defined
val pairSecondInst: InferedPair[String, String]
= InferedPair[String, String]("Husband", "Wife")
प्रकार के अनुमान का उपरोक्त रूप डायमंड ऑपरेटर के समान है, जिसे जावा 7 में पेश किया गया है।
प्रवेश की सीमाएं
ऐसे परिदृश्य हैं जिनमें स्काला टाइप-इनफेरेंस काम नहीं करता है। उदाहरण के लिए, कंपाइलर विधि मापदंडों के प्रकार का अनुमान नहीं लगा सकता है:
def add(a, b) = a + b // Does not compile
def add(a: Int, b: Int) = a + b // Compiles
def add(a: Int, b: Int): Int = a + b // Equivalent expression, compiles
कंपाइलर पुनरावर्ती तरीके के रिटर्न प्रकार का अनुमान नहीं लगा सकता है:
// Does not compile
def factorial(n: Int) = if (n == 0 || n == 1) 1 else n * factorial(n - 1)
// Compiles
def factorial(n: Int): Int = if (n == 0 || n == 1) 1 else n * factorial(n - 1)
कुछ भी नहीं रोक रहा है
इस ब्लॉग पोस्ट पर आधारित
मान लें कि आपके पास एक तरीका है:
def get[T]: Option[T] = ???
जब आप जेनेरिक पैरामीटर को निर्दिष्ट किए बिना इसे कॉल करने का प्रयास करते हैं, तो Nothing
अनुमान Nothing
लगाया जाता है, जो वास्तविक कार्यान्वयन के लिए बहुत उपयोगी नहीं है (और इसका परिणाम उपयोगी नहीं है)। निम्नलिखित समाधान के साथ NotNothing
अपेक्षित प्रकार निर्दिष्ट किए बिना बाध्य पद्धति का उपयोग करके रोका जा सकता है संदर्भ (इस उदाहरण में RuntimeClass
भी के लिए के रूप में बाहर रखा गया है ClassTags
नहीं Nothing
, लेकिन RuntimeClass
मान लिया जाता है):
@implicitNotFound("Nothing was inferred")
sealed trait NotNothing[-T]
object NotNothing {
implicit object notNothing extends NotNothing[Any]
//We do not want Nothing to be inferred, so make an ambigous implicit
implicit object `\n The error is because the type parameter was resolved to Nothing` extends NotNothing[Nothing]
//For classtags, RuntimeClass can also be inferred, so making that ambigous too
implicit object `\n The error is because the type parameter was resolved to RuntimeClass` extends NotNothing[RuntimeClass]
}
object ObjectStore {
//Using context bounds
def get[T: NotNothing]: Option[T] = {
???
}
def newArray[T](length: Int = 10)(implicit ct: ClassTag[T], evNotNothing: NotNothing[T]): Option[Array[T]] = ???
}
उदाहरण उपयोग:
object X {
//Fails to compile
//val nothingInferred = ObjectStore.get
val anOption = ObjectStore.get[String]
val optionalArray = ObjectStore.newArray[AnyRef]()
//Fails to compile
//val runtimeClassInferred = ObjectStore.newArray()
}