я узнал о пылеудаляющих лестничной книги:Как работает экстрактор, когда функция `unapply` возвращает Boolean вместо опции?
object Twice {
def apply(x: Int) = x * 2
def unapply(x: Int) = if(x % 2 == 0) Some(x/2) else None
}
// outside pattern mathcing, Twice.apply(21) is called
val x = Twice(21)
x match {
// inside pattern matching, Twice.unapply(x) is called,
// the result Some(21) is matched against y,
// y gets the value 21
case Twice(y) => println(x + " is twice " + y)
case _ => println(x + " is odd.")
}
Это довольно прямо вперед. Но сегодня я прочитал с какой-то книге на рамках Play этот код:
trait RequestExtractors extends AcceptExtractors {
//Convenient extractor allowing to apply two extractors.
object & {
def unapply(request: RequestHeader): Option[(RequestHeader, RequestHeader)] = Some((request, request))
}
}
//Define a set of extractors allowing to pattern match on the Accept HTTP header of a request
trait AcceptExtractors {
//Common extractors to check if a request accepts JSON, Html, etc.
object Accepts {
import play.api.http.MimeTypes
val Json = Accepting(MimeTypes.JSON)
val Html = Accepting(MimeTypes.HTML)
val Xml = Accepting(MimeTypes.XML)
val JavaScript = Accepting(MimeTypes.JAVASCRIPT)
}
}
//Convenient class to generate extractors checking if a given mime type matches the Accept header of a request.
case class Accepting(val mimeType: String) {
def unapply(request: RequestHeader): Boolean = request.accepts(mimeType)
def unapply(mediaRange: play.api.http.MediaRange): Boolean = mediaRange.accepts(mimeType)
}
def fooBar = Action {
implicit request =>
val xmlResponse: Node = <metadata>
<company>TinySensors</company>
<batch>md2907</batch>
</metadata>
val jsonResponse = Json.obj("metadata" -> Json.arr(
Json.obj("company" -> "TinySensors"),
Json.obj("batch" -> "md2907"))
)
render {
case Accepts.Xml() => Ok(xmlResponse)
case Accepts.Json() & Accepts.JavaScript() => Ok(jsonResponse)
}
}
Как экстрактор работа, когда функция unapply
возвращает Boolean вместо опции? Как сделать &
, Accepts.Xml
работа здесь?
Экстракторы должны быть определены в сопутствующем объекте, а не в самом классе. – PhilBa
Возвращаясь к вашему примеру воспроизведения, он, кажется, используется для указания, какие MIME вы хотите принять, и как вы хотите их обрабатывать. – PhilBa
Я немного переписал ваш пример и разместил его на github: https://gist.github.com/Phil-Ba/7725cba259973834ae70#file-extractor-scala – PhilBa