Статьи

Краткое введение в использование Option и любого из классов

Ранее я писал о  классах Companion в Scala,  и там я упомянул одно из его применений — определение метода apply для поддержки литералов объектов. В этом посте я продолжаю, где я раньше оставил и выбрать два таких класса Companion в Scala API называется  класс Option  и  класс Либо  и связанные с ними  классы регистра .

В этом посте я хотел бы осветить:

Каковы тематические классы?

Из  официального документа Scala Doc :

Scala поддерживает понятие case-классов. Классы case — это обычные классы, которые экспортируют свои параметры конструктора и предоставляют рекурсивный механизм декомпозиции через сопоставление с образцом.

Примеры классов case включают  scala.Somescala.util.Leftscala.util.Right . А применение тематических классов можно прочитать в следующих темах.

Что такое класс Option?

Из Scala API, класс Option:

Представляет необязательные значения. Экземпляры Option являются экземпляром  scala.Some  или объектом None.

До Java 8 не поддерживалось создание объектов, которые либо содержат некоторое значение, либо не содержат никакого значения. Эта поддержка была предоставлена ​​внешними API, такими как Guava и другими. В Java 8 добавлен новый класс под названием  Optional (я бы написал об этом когда-нибудь в будущем).

Существует 2 варианта Option, а именно Some и None. Первый представляет наличие значения и хранит значение внутри него, а второй представляет отсутствие значения. Давайте посмотрим на пример:

//Uses of Option class
object OptionDemo {
  def main(args: Array[String]) {   
    val result1 = loadData(true)
    val result2 = loadData(false)
    println(result1.getClass())//Prints class scala.Some
    println(result2.getClass())//Prints class scala.None$

    //getOrElse- either returns the value present or 
    //returns the value after evaluating the parameter.
    println(result1.getOrElse("Error!"))
    println(result2.getOrElse("Error!"))
    
  }

  def loadData(condition: Boolean): Option[String] =
    if (condition) {
      Some("Data found!")
    } else {
      None
    }

}

В вышеприведенном простом примере экземпляр Some или singleton None возвращается на  loadDataоснове некоторого условия и затем использует возвращаемые значения для распечатки их типов, а также их содержимого с использованием  getOrElse метода. Давайте посмотрим, как можно использовать возвращаемые значения из  loadData метода. В приведенном ниже примере мы используем расширенный механизм сопоставления с образцом для извлечения содержимого объекта. Это возможно, потому что классы Some и None есть  case classes.

object OptionDemo {
  def main(args: Array[String]) {   
    val result1 = loadData(true)
    val result2 = loadData(false)
    
    //Prints: found details:Data for employee 1234
    matcher(result1)
    //Prints: No data found
    matcher(result2)
  }
  
  //Using pattern matching to decompose the parameter.
  def matcher(result: Option[String]){
    result match{
      case Some(msg) => println("found details:" + msg)
      case None      => println("No data found")
    }
  }

  def loadData(condition: Boolean): Option[String] =
    if (condition) {
      Some("Data for employee 1234")
    } else {
      None
    }

}

Что такое Либо класс?

Из Scala API любой класс:

Представляет значение одного из двух возможных типов (дизъюнктное объединение). Экземпляры Either являются экземплярами  scala.util.Left  или  scala.util.Right .

И сразу после этого говорится об использовании любого из классов:

Обычное использование Either является альтернативой scala.Option для работы с возможными пропущенными значениями. В этом случае  scala.None  заменяется на  scala.util.Left,  который может содержать полезную информацию. scala.util. Право  занимает место  scala.Some . Конвенция гласит, что левый используется для неудачи, а правый — для успеха.

В приведенном ниже примере мы используем класс Left для заполнения данных, если какая-то операция прошла успешно, и используем класс Right для заполнения сообщения об исключении в случае сбоя. Условие успеха — когда переданное число является четным, а условие сбоя — когда переданное число является нечетным.

object EitherDemo {
  def main(args: Array[String]) {
    val div1 = even(12)
    val div2 = even(11)
    matcher(div1)//Prints 12.0
    matcher(div2)//Prints "The number 11.0 is not even"
    
  }
  
  def matcher(matchElement:Either[String, Double]){
    matchElement match {
      case Left(msg) => println(msg)
      case Right(rem) => println(rem)
    }
  }

  def even(number:Double): Either[String, Double] =
    if (number % 2 == 0) {
      Right(number)
    } else {
      Left("The number "+ number +" is not even");
    }

}

В приведенном выше примере левый и правый регистр классов использовались в сопоставлении с образцом так же, как классы Some и None использовались в первом примере.

Это было очень кратко о классах Option и Either в Scala и о том, как классы case можно использовать для сопоставления с образцом.