जवाबों:
तो, कड़ाई से बोलते हुए, "एक प्रकार का चर" हमेशा मौजूद होता है, और इसे एक प्रकार के पैरामीटर के रूप में पास किया जा सकता है। उदाहरण के लिए:
val x = 5
def f[T](v: T) = v
f(x) // T is Int, the type of x
लेकिन आप क्या करना चाहते हैं , इसके आधार पर , यह आपकी मदद नहीं करेगा। उदाहरण के लिए, यह जानना नहीं चाह सकते हैं कि चर का प्रकार क्या है, लेकिन यह जानने के लिए कि क्या मूल्य का प्रकार कुछ विशिष्ट प्रकार है, जैसे कि:
val x: Any = 5
def f[T](v: T) = v match {
case _: Int => "Int"
case _: String => "String"
case _ => "Unknown"
}
f(x)
यहाँ यह कोई फर्क नहीं पड़ता कि चर का प्रकार क्या है Any
,। क्या मायने रखता है, क्या जांचा जाता है, का प्रकार है 5
, मूल्य। वास्तव में, T
बेकार है - आप इसके def f(v: Any)
बजाय इसे लिख सकते हैं। इसके अलावा, यह ClassTag
या तो एक मान का उपयोग करता है Class
, जिसे नीचे समझाया गया है, और एक प्रकार के प्रकार के मापदंडों की जांच नहीं कर सकता है: आप जांच सकते हैं कि क्या कुछ List[_]
( List
कुछ का) है, लेकिन यह नहीं है कि यह उदाहरण के लिए है, List[Int]
या एक List[String]
।
एक अन्य संभावना यह है कि आप चर के प्रकार को संशोधित करना चाहते हैं । यही है, आप प्रकार को एक मूल्य में बदलना चाहते हैं, इसलिए आप इसे स्टोर कर सकते हैं, इसे पास कर सकते हैं, आदि। इसमें प्रतिबिंब शामिल है, और आप ClassTag
या तो या एक का उपयोग करेंगे TypeTag
। उदाहरण के लिए:
val x: Any = 5
import scala.reflect.ClassTag
def f[T](v: T)(implicit ev: ClassTag[T]) = ev.toString
f(x) // returns the string "Any"
A ClassTag
आपको आपके द्वारा प्राप्त किए गए प्रकार के मापदंडों का उपयोग करने देगा match
। यह काम नहीं करेगा:
def f[A, B](a: A, b: B) = a match {
case _: B => "A is a B"
case _ => "A is not a B"
}
लेकिन यह होगा:
val x = 'c'
val y = 5
val z: Any = 5
import scala.reflect.ClassTag
def f[A, B: ClassTag](a: A, b: B) = a match {
case _: B => "A is a B"
case _ => "A is not a B"
}
f(x, y) // A (Char) is not a B (Int)
f(x, z) // A (Char) is a B (Any)
यहां मैं संदर्भ सीमा सिंटैक्स का उपयोग कर रहा हूं B : ClassTag
, जो पिछले ClassTag
उदाहरण में निहित पैरामीटर की तरह काम करता है , लेकिन एक अनाम चर का उपयोग करता है।
कोई भी इस तरह ClassTag
से मूल्य प्राप्त कर सकता है Class
:
val x: Any = 5
val y = 5
import scala.reflect.ClassTag
def f(a: Any, b: Any) = {
val B = ClassTag(b.getClass)
ClassTag(a.getClass) match {
case B => "a is the same class as b"
case _ => "a is not the same class as b"
}
}
f(x, y) == f(y, x) // true, a is the same class as b
A इसमें ClassTag
सीमित है कि यह केवल आधार वर्ग को कवर करता है, लेकिन इसके प्रकार के मापदंडों को नहीं। है यही कारण है, ClassTag
के लिए List[Int]
और List[String]
एक ही है, List
। यदि आपको टाइप पैरामीटर की आवश्यकता है, तो आपको TypeTag
इसके बजाय उपयोग करना होगा । एक TypeTag
तथापि, JVM के की वजह से एक मूल्य से प्राप्त नहीं किया जा सकता, न ही यह एक पैटर्न मैच पर इस्तेमाल किया जा सकता, विलोपन ।
इसके उदाहरण TypeTag
काफी जटिल हो सकते हैं - दो प्रकार के टैगों की तुलना करना भी बिल्कुल सरल नहीं है, जैसा कि नीचे देखा जा सकता है:
import scala.reflect.runtime.universe.TypeTag
def f[A, B](a: A, b: B)(implicit evA: TypeTag[A], evB: TypeTag[B]) = evA == evB
type X = Int
val x: X = 5
val y = 5
f(x, y) // false, X is not the same type as Int
बेशक, उस तुलना को सही बनाने के तरीके हैं, लेकिन वास्तव में कवर करने के लिए कुछ पुस्तक अध्यायों की आवश्यकता होगी TypeTag
, इसलिए मैं यहां रुकूंगा।
अंत में, शायद आप चर के प्रकार के बारे में बिल्कुल भी परवाह नहीं करते हैं। हो सकता है कि आप केवल जानना चाहते हों कि मूल्य का वर्ग क्या है, जिस स्थिति में उत्तर सरल है:
val x = 5
x.getClass // int -- technically, an Int cannot be a class, but Scala fakes it
हालांकि, यह बेहतर होगा कि आप जो हासिल करना चाहते हैं, उसके बारे में अधिक विशिष्ट होना चाहिए, ताकि उत्तर बिंदु से अधिक हो सके।
Int
है Any
, लेकिन Any
नहीं है Int
। यह स्कैला 2.10 पर काम करता है, और इसे स्कला 2.11 पर काम करना चाहिए , और मुझे नहीं पता कि यह क्यों नहीं है।
a match { case _: B => ...
चर के वास्तविक मूल्य के प्रकार का परीक्षण करता है, चर a
के प्रकार का नहीं a
। आप इसमें सही हैं कि आप 2.10.6 में जो कहते हैं उसे वापस कर देते हैं। लेकिन यह एक बग होना चाहिए। स्कला 2.11.8 में वास्तविक मान के प्रकार का परीक्षण किया जाता है, जैसा कि इसे करना चाहिए।
मुझे लगता है कि सवाल अधूरा है। यदि आपका मतलब है कि आप कुछ टाइपकास्ट की जानकारी प्राप्त करना चाहते हैं तो नीचे:
यदि आप प्रिंट करना चाहते हैं तो आपने निर्दिष्ट किया है:
scala> def manOf[T: Manifest](t: T): Manifest[T] = manifest[T]
manOf: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T]
scala> val x = List(1,2,3)
x: List[Int] = List(1, 2, 3)
scala> println(manOf(x))
scala.collection.immutable.List[Int]
यदि आप उत्तर मोड में हैं तो
scala> :type List(1,2,3)
List[Int]
या यदि आप केवल यह जानना चाहते हैं कि वर्ग प्रकार क्या है तो @monkjack बताते हैं "string".getClass
कि यह उद्देश्य हल कर सकता है
typeof x
, यहाँ manOf(x)
डेटा प्रकार कहते हैं!
यदि एक चर के प्रकार से आपका मतलब उस वस्तु के रनटाइम वर्ग से है जो चर इंगित करता है, तो आप इसे कक्षा संदर्भ के माध्यम से प्राप्त कर सकते हैं जो सभी वस्तुओं में है।
val name = "sam";
name: java.lang.String = sam
name.getClass
res0: java.lang.Class[_] = class java.lang.String
यदि आप फिर भी उस प्रकार का मतलब है जो चर के रूप में घोषित किया गया था, तो आपको वह नहीं मिल सकता है। जैसे, यदि आप कहें
val name: Object = "sam"
तब आपको String
उपरोक्त कोड से वापस मिल जाएगा ।
name.getClass.getSimpleName
अधिक पठनीय आउटपुट के लिए भी कर सकते हैं
मैंने परीक्षण किया है और यह काम किया है
val x = 9
def printType[T](x:T) :Unit = {println(x.getClass.toString())}
5
दोनों का एक उदाहरण हैInt
और एक उदाहरण हैAny
। इसके अलावा, आपका स्पष्टीकरण एकदम सही था :)