Scala Language
एक्सट्रैक्टर्स
खोज…
वाक्य - विन्यास
- वैल एक्सट्रैक्टर्स (एक्सट्रैक्टडाल्यू 1, _ / * दूसरे निकाले गए मूल्य को अनदेखा किया * /) = valueToBextxted
- valueToBeExtracted मैच {केस एक्सट्रैक्टर (निकाले गए VVue1, _) => ???}
- वैल (tuple1, tuple2, tuple3) = tupleWith3Elements
- ऑब्जेक्ट फू {डि अनप्ली (फू: फू): विकल्प [स्ट्रिंग] = कुछ (foo.x); }
टपल निकालनेवाला
x
और y
टपल से निकाले जाते हैं:
val (x, y) = (1337, 42) // x: Int = 1337 // y: Int = 42
मान उपयोग को अनदेखा करने के लिए _
:
val (_, y: Int) = (1337, 42) // y: Int = 42
चिमटा निकालने के लिए:
val myTuple = (1337, 42) myTuple._1 // res0: Int = 1337 myTuple._2 // res1: Int = 42
ध्यान दें कि ._1
की अधिकतम लंबाई 22 है, और इस प्रकार ._1
थ्रू ._22
काम करेगा (यह देखते हुए कि टपल कम से कम आकार का है)।
ट्यूपल एक्सट्रैक्टर्स का उपयोग शाब्दिक कार्यों के लिए प्रतीकात्मक तर्क प्रदान करने के लिए किया जा सकता है:
val persons = List("A." -> "Lovelace", "G." -> "Hopper") val names = List("Lovelace, A.", "Hopper, G.") assert { names == (persons map { name => s"${name._2}, ${name._1}" }) } assert { names == (persons map { case (given, surname) => s"$surname, $given" }) }
केस क्लास एक्सट्रैक्टर्स
एक केस क्लास एक ऐसा वर्ग है जिसमें बहुत सारे मानक बॉयलरप्लेट कोड स्वचालित रूप से शामिल होते हैं। इसका एक लाभ यह है कि स्काला केस केस के साथ एक्सट्रैक्टर्स का उपयोग करना आसान बनाता है।
case class Person(name: String, age: Int) // Define the case class
val p = Person("Paola", 42) // Instantiate a value with the case class type
val Person(n, a) = p // Extract values n and a
// n: String = Paola
// a: Int = 42
इस मोड़ पर, दोनों n
और a
हैं val
कार्यक्रम में और इस तरह के रूप पहुँचा जा सकता है: वे किया गया है पी से 'निकाले' कहा जाता है। को जारी रखते हुए:
val p2 = Person("Angela", 1337)
val List(Person(n1, a1), Person(_, a2)) = List(p, p2)
// n1: String = Paola
// a1: Int = 42
// a2: Int = 1337
यहाँ हम दो महत्वपूर्ण बातें देखते हैं:
- निष्कर्षण 'गहरे' स्तरों पर हो सकता है: नेस्टेड वस्तुओं के गुण निकाले जा सकते हैं।
- सभी तत्वों को निकालने की आवश्यकता नहीं है। वाइल्डकार्ड
_
चरित्र इंगित करता है कि विशेष मूल्य कुछ भी हो सकता है, और इसे अनदेखा किया जाता है। कोईval
नहीं बनी है।
विशेष रूप से, यह संग्रह के मिलान को आसान बना सकता है:
val ls = List(p1, p2, p3) // List of Person objects
ls.map(person => person match {
case Person(n, a) => println("%s is %d years old".format(n, a))
})
यहाँ, हम कोड निकालने का उपयोग करता है स्पष्ट रूप से जाँच करने के लिए कि person
एक है Person
: वस्तु और तुरंत चर बाहर खींच के बारे में है कि हम परवाह n
और a
।
अनुपयोगी - कस्टम एक्सट्रैक्टर्स
एक कस्टम निकासी को लागू करने से लिखा जा सकता है unapply
विधि और प्रकार का एक मूल्य के लौटने Option
:
class Foo(val x: String)
object Foo {
def unapply(foo: Foo): Option[String] = Some(foo.x)
}
new Foo("42") match {
case Foo(x) => x
}
// "42"
वापसी का प्रकार unapply
से Option
अलावा कुछ और हो सकता है, बशर्ते कि लौटाया गया प्रकार get
और isEmpty
तरीके हैं। इस उदाहरण में, Bar
को उन तरीकों से परिभाषित किया गया है, और unapply
से Bar
का एक उदाहरण देता है:
class Bar(val x: String) {
def get = x
def isEmpty = false
}
object Bar {
def unapply(bar: Bar): Bar = bar
}
new Bar("1337") match {
case Bar(x) => x
}
// "1337"
की वापसी प्रकार unapply
कर सकते हैं यह भी एक हो Boolean
है, जो एक विशेष मामला है कि नहीं होता है get
और isEmpty
ऊपर दी गई आवश्यकताओं। हालाँकि, इस उदाहरण में ध्यान दें कि DivisibleByTwo
एक ऑब्जेक्ट है, न कि एक क्लास, और एक पैरामीटर नहीं लेता है (और इसलिए यह पैरामीटर बाध्य नहीं हो सकता है):
object DivisibleByTwo {
def unapply(num: Int): Boolean = num % 2 == 0
}
4 match {
case DivisibleByTwo() => "yes"
case _ => "no"
}
// yes
3 match {
case DivisibleByTwo() => "yes"
case _ => "no"
}
// no
याद रखें कि unapply
में एक वर्ग के साथी वस्तु में जाता है, कक्षा में नहीं। यदि आप इस भेद को समझते हैं तो उपरोक्त उदाहरण स्पष्ट होगा।
चिमटा इन्फिक्स संकेतन
यदि किसी केस क्लास के पास दो मान हैं, तो उसके एक्स्ट्रेक्टर का उपयोग इन्फिक्स नोटेशन में किया जा सकता है।
case class Pair(a: String, b: String)
val p: Pair = Pair("hello", "world")
val x Pair y = p
//x: String = hello
//y: String = world
कोई भी एक्सट्रैक्टर जो 2-ट्यूपल लौटाता है वह इस तरह से काम कर सकता है।
object Foo {
def unapply(s: String): Option[(Int, Int)] = Some((s.length, 5))
}
val a Foo b = "hello world!"
//a: Int = 12
//b: Int = 5
रेगेक्स एक्सट्रैक्टर्स
समूहीकृत भागों के साथ एक नियमित अभिव्यक्ति एक चिमटा के रूप में इस्तेमाल किया जा सकता है:
scala> val address = """(.+):(\d+)""".r
address: scala.util.matching.Regex = (.+):(\d+)
scala> val address(host, port) = "some.domain.org:8080"
host: String = some.domain.org
port: String = 8080
ध्यान दें कि जब इसका मिलान नहीं किया जाता है, तो MatchError
को रनटाइम पर फेंक दिया जाएगा:
scala> val address(host, port) = "something not a host and port"
scala.MatchError: something not a host and port (of class java.lang.String)
ट्रांसफॉर्मर एक्सट्रैक्टर्स
एक्सट्रैक्टर व्यवहार का उपयोग उनके इनपुट से मनमाने मूल्यों को प्राप्त करने के लिए किया जा सकता है। यह उन परिदृश्यों में उपयोगी हो सकता है जहाँ आप उस परिवर्तन के परिणामों पर कार्य करने में सक्षम होना चाहते हैं जो परिवर्तन सफल है।
एक उदाहरण के रूप में विचार करें कि विभिन्न उपयोगकर्ता नाम विंडोज वातावरण में प्रयोग करने योग्य हैं :
object UserPrincipalName {
def unapply(str: String): Option[(String, String)] = str.split('@') match {
case Array(u, d) if u.length > 0 && d.length > 0 => Some((u, d))
case _ => None
}
}
object DownLevelLogonName {
def unapply(str: String): Option[(String, String)] = str.split('\\') match {
case Array(d, u) if u.length > 0 && d.length > 0 => Some((d, u))
case _ => None
}
}
def getDomain(str: String): Option[String] = str match {
case UserPrincipalName(_, domain) => Some(domain)
case DownLevelLogonName(domain, _) => Some(domain)
case _ => None
}
वास्तव में यह एक प्रकार का चिमटा बनाने के लिए संभव है जो दोनों प्रकार के व्यवहारों को प्रदर्शित कर सके जो इसे मिला सकते हैं।
object UserPrincipalName {
def unapply(obj: Any): Option[(String, String)] = obj match {
case upn: UserPrincipalName => Some((upn.username, upn.domain))
case str: String => str.split('@') match {
case Array(u, d) if u.length > 0 && d.length > 0 => Some((u, d))
case _ => None
}
case _ => None
}
}
सामान्य तौर पर, एक्स्ट्रेक्टर केवल Option
पैटर्न का एक सुविधाजनक सुधार है, जैसा कि tryParse
जैसे नामों के तरीकों पर लागू होता है:
UserPrincipalName.unapply("user@domain") match {
case Some((u, d)) => ???
case None => ???
}