Scala #4
-
Upload
alexander-podkhalyuzin -
Category
Engineering
-
view
171 -
download
1
Transcript of Scala #4
Patterns
Special unapplyclass A { def _1: Int = 1 def _2: String = "text"}
class B { def isEmpty = false def get = new A}
object K { def unapply(s: String): B = new B}
"text" match { case K(i, s) => println(i, s)}
Case classes moreТеперь понятнее, что же на самом деле дает case class:case class Person(name: String)val ivan = Person("ivan")ivan.nameivan match { case Person(name) =>}
Multiline stringsМногострочные литералы:val s = """ |Some text. |<- This is margin. |It will be stripped below. """.stripMargin
Interpolated stringsМожно использовать разные интерполяторы. Дефолтные - это s и f:val name = "Alexander"val city = "Saint-Petersburg"s"My name is $name. I live in $city."val height = 1.8311df"$name%s’s height is $height%2.2f"
Regular expressionsval Decimal = """(-)?(\d+)(\.\d*)?""".r"1.0" match { case Decimal(sign, i, d) => case _ =>}val Decimal(sign, i, d) = "1.0"val iterator = Decimal findAllIn "1.0 and 2.0, 33"for (Decimal(sign, i, d) <- iterator) { println(i)}
unapplySeqobject ListLike { def unapplySeq[T](l: List[T]): Option[Seq[T]] = Some(l)}List(1, 2, 3) match{ case ListLike(1, xs@_*) => println(xs) case _ =>}
Other patternsobject ** { def unapply(t: (Int, Int)): Some[(Int, Int)] = Some(t)}val x, y: Int = 1(x, y) match { case (1, 2) | (2, 1) => case 1 ** 1 =>}
Pattern guardsМожно накладывать условия на case clause:val x, y: Int = 1(x, y) match { case (a, b) if a == b => case _ =>}
ScopesScopes - это место в коде, где может быть объявлена переменная. ● { - начинает новый scope, кроме классов ● Каждый генератор в for statement начинает
новый scope ● Функция начинает новый scope для
параметров ● Case clause начинает новый scope Переменная объявленная внутри одного scope не видна снаружи.
Names shadowingВо внутреннем scope можно скрывать имя определенное во внешнем scope при условии, что приоритет этого имени не ниже чем у имени объявленного снаружи.
Это ошибка объявить переменные с одним именем внутри одного и того же scope.
Существует два вида имен: expressions, types.
Implicits
Implicit conversionsПреследует две главные цели:● Extension methods● DSL languages
Позволяет неявно в коде конвертировать один тип в другой.
Implicit conversionsПростейшие примеры:class RichString(s: String) { def double: String = s + s}implicit def s2r(s: String): RichString = new RichString(s)
"text".doubleval r: RichString = "text""""^[^\d].*""".r
Implicit classesВ Scala 2.10 есть более простой вариант:implicit class RichString(s: String) { def double: String = s + s}
"text".double
Value classesPerformance overhead на удаление в GC новых объектов существенный. Поэтому для extension methods можно сделать так:
implicit class RichString(val s: String) extends AnyVal { def double: String = s + s}"text".double
Implicits search1. Сначала ищем в scope2. Если не нашли, то расширяем scope с
помощью companion objects частей типа, для которого ищем конверсию
How to debug implicits?Неявно это хорошо, когда все работает.Что делать, если не работает:● -Xprint:typer параметр для компилятора● IntelliJ IDEA view implicits tools
Magnet patternПример использования implicits:● Нет проблемы с type erasure для
перегруженных методов● Автоматически выносится общая часть
для перегруженных методов● Использование функциональных типов с
перегрузкой
HomeworkНаписать интерпретируемый язык программирования. Синтаксис и все остальное дело вашего вкуса. Базовая спецификация следующая:1. Динамически типизируемый. У целых и вещественных чисел нет переполнения.2. Можно объявлять целые, вещественные и стоковые литералы.3. Можно объявлять переменные и функции. В функциях можно задавать значения по умолчанию.4. Можно эти переменные и функции вызывать.5. Можно создавать структуры без наследования. Просто данные, и возможно какие-то методы.