Spesso è necessario passare attraverso le informazioni di contesto del codice come l'utente che sta eseguendo l'azione. Usiamo questo contesto per varie cose come i controlli di autorizzazione. In questi casi i valori impliciti possono rivelarsi molto utili per ridurre il codice della piastra della caldaia.scala valori impliciti estratti nella corrispondenza del modello?
Diciamo che abbiamo un contesto di semplice esecuzione che passiamo in giro: case class EC(initiatingUser:User)
Possiamo avere guardie a portata di mano:
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
}
di recente ho trovato me stesso in bisogno di fare questo quando si lavora con gli attori Akka ma fanno uso di pattern matching e devo ancora trovare un buon modo per far funzionare bene gli impliciti con gli estrattori.
In primo luogo si avrebbe bisogno di passare il contesto di ogni comando, ma questo è facile:
case class DeleteCommand(entityId:Long)(implicit executionContext:EC)
//note that you need to overwrite unapply to extract that context
Ma la funzione di ricezione è simile al seguente:
class MyActor extends Actor{
def receive = {
case DeleteCommand(entityId, context) => {
implicit val c = context
sender ! onlyAdmins{
//do something adminy that also uses context
}
}
}
}
Sarebbe molto più semplice se le variabili estratte potrebbe essere contrassegnato come implicito ma non ho visto questa funzione:
def receive = {
case DeleteCommand(entityId, implicit context) => sender ! onlyAdmins{
//do something adminy (that also uses context)
}
}
Ar Sei a conoscenza di altri modi alternativi di codifica, in modo da ridurre il codice dello standard?
Potreste essere interessato a questo: http://stackoverflow.com/questions/6156656/how-to-pattern-match-a-class-with-multiple-argument-lists – gzm0
questo suona come quello GADTs fare in Haskell, se si considera la somiglianza dei contesti di typeclass in impliciti. Potrebbe anche fornire un modo più efficace per fare corrispondenze di pattern simili a GADT in Scala che funzioni bene. –