Нам часто приходится проходить через контекстную информацию кода, такую как пользователь, выполняющий действие. Мы используем этот контекст для различных вещей, таких как проверки полномочий. В этих случаях неявные значения могут оказаться очень полезными для уменьшения кода плиты котла.scala неявные извлеченные значения в сопоставлении с образцом?
Допустим, у нас есть простой контекст выполнения, который мы пройти вокруг: case class EC(initiatingUser:User)
Мы можем иметь под рукой охранникам:
def onlyAdmins(f: => T)(implicit context:EC) = context match{
case EC(u) if(u.roles.contain(Role.ADMIN)) => f
case _ => throw new UnauthorizedException("Only admins can perform this action")
}
val result = onlyAdmins{
//do something adminy
}
Недавно я нашел себя в необходимости делать это при работе с Akka актерами, но они используют сопоставление с образцом, и я еще не нашел хороший способ сделать импликации хорошо работать с экстракторами.
Сначала вам нужно будет пройти контекст с каждой командой, но это легко:
case class DeleteCommand(entityId:Long)(implicit executionContext:EC)
//note that you need to overwrite unapply to extract that context
Но получить функция выглядит следующим образом:
class MyActor extends Actor{
def receive = {
case DeleteCommand(entityId, context) => {
implicit val c = context
sender ! onlyAdmins{
//do something adminy that also uses context
}
}
}
}
Было бы намного проще, если добытых переменных могут быть помечены как неявные, но я не видел эту функцию:
def receive = {
case DeleteCommand(entityId, implicit context) => sender ! onlyAdmins{
//do something adminy (that also uses context)
}
}
Ar Вы знаете какие-либо альтернативные способы кодирования, чтобы уменьшить код шаблона?
Вы могли бы быть заинтересованы в этом: http://stackoverflow.com/questions/6156656/how-to-pattern-match-a-class-with-multiple-argument-lists – gzm0
Это звучит как что GADTs делать в Haskell, если вы считаете, что сходство контекстов типов классов подразумевает. Это может также обеспечить более принципиальный способ сделать подобный GADT сопоставление шаблонов в Scala, который прекрасно работает. –