Как именно "case" работает в частичных функциях в Scala?

Я только начинаю свою, казалось бы, крутую кривую обучения со Scala и не совсем понимаю, как именно "кейс" работает в частичных функциях.

Я посмотрел на определение самой PartialFunction, и там я вижу пример, подобный следующему:

val isEven: PartialFunction[Int, String] = { 
   case x if x % 2 == 0 => x+" is even" 
}

Часть, в которой я застреваю, это случай x, если x% 2 - как Scala узнает, что здесь происходит? Каково формальное определение этого "падежного" утверждения / ключевого слова?

Я думаю, что одна причина моего замешательства заключается в том, что в Lift я вижу такие вещи, как (в классах Actor):

override def messageHandler = {
   case SomeKindOfUserMessageClass(id1, param1) => ....
   case AnotherKindOfUserMessageClass(id2) => ....
}

Я вроде как интуитивно понимаю, что здесь происходит, но не могу собрать какое-то единое определение того, как следует использовать "случай". Еще более загадочным для меня является то, как компилятор Scala распутывает все это.

4 ответа

Решение

То, о чем вы спрашиваете, называется сопоставлением с образцом. Блок сопоставления с образцом может использоваться с match ключевое слово или его можно использовать для определения функции или частичной функции в зависимости от контекста.

Ваш второй пример использует экстракторы. Оценка Скалы m match { case A(x) => } включает в себя вызов A.unapply(m), Сопутствующий объект класса case является экстрактором (использование классов case встречается чаще, чем на самом деле unapply метод).

Спецификация языка Scala довольно сложна, но иногда стоит взглянуть на нее, особенно если вы ищете формализм. Глава 8 о сопоставлении с образцом. Раздел 8.4 вводит идею использования if в кейсе, как в первом примере.

В разделе " Последовательности случаев как частичные функции" на странице http://www.artima.com/pins1ed/case-classes-and-pattern-matching.html я натолкнулся на следующие предложения, которые, на мой взгляд, также могут быть полезны. ответ на вопрос "как следует использовать дело".

A sequence of cases (i.e., alternatives) in curly braces can be used anywhere a function literal can be used. Essentially, a case sequence is a function literal, only more general. Вместо единой точки входа и списка параметров последовательность дел имеет несколько точек входа, каждая со своим списком параметров. Each case is an entry point to the function, and the parameters are specified with the pattern. The body of each entry point is the right-hand side of the case.

Думайте об этом как о переключателе на других языках.

В PHP вы должны использовать слово case перед каждым параметром. В ruby ​​вы бы использовали слово "когда"... и подобное на других языках.

Он запускается сверху вниз и выполняет код для первого соответствующего шаблона. Вы можете сопоставить, основываясь на значении, типе, конструкторе и т. Д.... и он запускает только один блок кода... и проверяет сверху вниз.

Это может быть в синтаксисе...

val x = List(1,2,3,4)
x match {
  case Nil => Nil
  case x => x map someFunction
}

или вы можете использовать сопоставление с образцом в лямбда-выражениях.

Ознакомьтесь с курсом функционального программирования в scala на coursera.org. Если бы вы приняли это, у вас был бы хороший пирог с головами в скале.

Думать о case например, соответствие некоторому условию или, если быть более точным, некоторый шаблон. Существуют различные способы указания шаблона.

case SomeKindOfUserMessageClass(id1, param1): Это говорит о том, что значение должно быть типа SomeKindOfUserMessageClass и если да, то уничтожить значения до id1 а также param1, Так что это похоже на условие с сопоставлением с шаблоном.

case x if x % 2 == 0Это говорит о том, что условие состоит в том, что значение должно делиться на 2, и если да, то связать значение с x ИЛИ вы можете сказать, привязать значение к x и проверьте, делится ли это на 2.

Другие вопросы по тегам