खोज…


टिप्पणियों

सीरियलाइज़ेशन की समस्याओं से बचने के लिए, विशेष रूप से वितरित वातावरण (जैसे अपाचे स्पार्क ) में, टाइप क्लास उदाहरणों के लिए Serializable विशेषता को लागू करने के लिए यह सबसे अच्छा अभ्यास है।

सिंपल टाइप क्लास

एक प्रकार का वर्ग केवल एक या अधिक प्रकार के मापदंडों के साथ एक trait :

trait Show[A] {
  def show(a: A): String
}

एक प्रकार की कक्षा का विस्तार करने के बजाय, प्रत्येक समर्थित प्रकार के लिए प्रकार वर्ग का एक निहित उदाहरण प्रदान किया जाता है। टाइप क्लास के साथी ऑब्जेक्ट में इन कार्यान्वयनों को रखने से किसी विशेष आयात के बिना कार्य करने के लिए निहित संकल्प की अनुमति मिलती है:

object Show {
  implicit val intShow: Show[Int] = new Show {
    def show(x: Int): String = x.toString
  }

  implicit val dateShow: Show[java.util.Date] = new Show {
    def show(x: java.util.Date): String = x.getTime.toString
  }

  // ..etc
}

यदि आप यह गारंटी देना चाहते हैं कि फ़ंक्शन के लिए दिया गया जेनेरिक पैरामीटर एक प्रकार की श्रेणी का उदाहरण है, तो निहित मापदंडों का उपयोग करें:

def log[A](a: A)(implicit showInstance: Show[A]): Unit = {
  println(showInstance.show(a))
}

आप एक संदर्भ सीमा का उपयोग भी कर सकते हैं:

def log[A: Show](a: A): Unit = {
  println(implicitly[Show[A]].show(a))
}

उपरोक्त log विधि को किसी अन्य विधि की तरह कॉल करें। यह संकलन करने असफल हो जायेगी एक अंतर्निहित अगर Show[A] लागू करने के लिए नहीं पाया जा सकता A आप के पास log

log(10) // prints: "10"
log(new java.util.Date(1469491668401L) // prints: "1469491668401"
log(List(1,2,3)) // fails to compile with
                 // could not find implicit value for evidence parameter of type Show[List[Int]]

यह उदाहरण Show प्रकार वर्ग को लागू करता है। यह एक सामान्य प्रकार का वर्ग है जिसका उपयोग मनमाने प्रकार के उदाहरणों को String एस में परिवर्तित करने के लिए किया जाता है। भले ही हर वस्तु में एक toString विधि होती है, लेकिन यह हमेशा स्पष्ट नहीं होता है कि क्या एक उपयोगी तरीके से toString को परिभाषित किया गया है या नहीं। Show प्रकार वर्ग के उपयोग के साथ, आप गारंटी दे सकते हैं कि log करने के लिए पारित कुछ भी String लिए एक अच्छी तरह से परिभाषित रूपांतरण है।

एक प्रकार वर्ग का विस्तार

इस उदाहरण में निम्न प्रकार वर्ग के विस्तार पर चर्चा की गई है।

trait Show[A] {
  def show: String
}

एक वर्ग बनाने के लिए जिसे आप नियंत्रित करते हैं (और स्कैला में लिखा जाता है) प्रकार की कक्षा का विस्तार करते हैं, इसके साथी ऑब्जेक्ट में निहित जोड़ते हैं। हमें बताएंगे कि कैसे हम प्राप्त कर सकते हैं Person से वर्ग इस उदाहरण का विस्तार करने के Show :

class Person(val fullName: String) {    
  def this(firstName: String, lastName: String) = this(s"$firstName $lastName")
}

हम इस वर्ग का विस्तार कर सकते हैं Person के साथी वस्तु के लिए एक जोड़कर Show :

object Person {
  implicit val personShow: Show[Person] = new Show {
    def show(p: Person): String = s"Person(${p.fullname})"
  }
}

एक साथी ऑब्जेक्ट क्लास के समान फ़ाइल में होना चाहिए , इसलिए आपको एक ही फ़ाइल में class Person और object Person दोनों की आवश्यकता होगी।

एक वर्ग बनाने के लिए जिसे आप नियंत्रित नहीं करते हैं, या स्कैला में नहीं लिखा जाता है, टाइप क्लास का विस्तार करें, टाइप क्लास के साथी ऑब्जेक्ट के लिए एक अंतर्निहित जोड़ें, जैसा कि सिंपल टाइप क्लास उदाहरण में दिखाया गया है।

यदि आप न तो क्लास और न ही टाइप क्लास को नियंत्रित करते हैं, तो ऊपर कहीं भी एक निहितार्थ बनाएं और इसे importसरल प्रकार वर्ग उदाहरण पर log विधि का उपयोग करना:

object MyShow {
  implicit val personShow: Show[Person] = new Show {
    def show(p: Person): String = s"Person(${p.fullname})"
  }
}

def logPeople(persons: Person*): Unit = {
  import MyShow.personShow
  persons foreach { p => log(p) }
}

टाइप करने के लिए टाइप क्लास फ़ंक्शंस जोड़ें

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

इसे समझने के लिए, आइए हम पहले एक साधारण प्रकार की क्लास बनाएँ:

// The mathematical definition of "Addable" is "Semigroup"
trait Addable[A] {
  def add(x: A, y: A): A
}

आगे हम गुणन को लागू करेंगे (टाइप क्लास को तत्काल):

object Instances {

  // Instance for Int
  // Also called evidence object, meaning that this object saw that Int learned how to be added
  implicit object addableInt extends Addable[Int] {
    def add(x: Int, y: Int): Int = x + y
  }

  // Instance for String
  implicit object addableString extends Addable[String] {
    def add(x: String, y: String): String = x + y
  }

}

फिलहाल यह हमारे जोड़ने योग्य उदाहरणों का उपयोग करने के लिए बहुत बोझिल होगा:

import Instances._
val three = addableInt.add(1,2)

हम केवल 1.add(2) लिखना 1.add(2) । इसलिए हम एक "ऑपरेशन क्लास" (जिसे "ऑप्स क्लास" भी कहा जाता है) Addable जो हमेशा एक प्रकार से अधिक Addable जो कि Addable लागू Addable

object Ops {
  implicit class AddableOps[A](self: A)(implicit A: Addable[A]) {
    def add(other: A): A = A.add(self, other)
  }
}

अब हम अपने नए फंक्शन add उपयोग कर सकते add जैसे कि यह Int और String का हिस्सा था:

object Main {

  import Instances._ // import evidence objects into this scope
  import Ops._       // import the wrappers

  def main(args: Array[String]): Unit = {

    println(1.add(5))
    println("mag".add("net"))
    // println(1.add(3.141)) // Fails because we didn't create an instance for Double

  }
}

"ऑप्स" कक्षाएं सिमुलकराम लाइब्रेरी में मैक्रोज़ द्वारा स्वचालित रूप से बनाई जा सकती हैं:

import simulacrum._

@typeclass trait Addable[A] {
  @op("|+|") def add(x: A, y: A): A
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow