2010-12-08 32 views
12

juste une question rapide, je semble être incapable de trouver une réponse à.Scala fermeture par défaut vide?

J'ai une définition de méthode Scala qui ressemble à ceci:

def execute(goals: List[String], 
      profiles: List[String] = List(), 
      loggingCallback: (String) => Unit = { _ => }): Result = { 
    // method body 
    loggingCallback("a message") 
} 

Je voudrais savoir s'il y a une meilleure façon de spécifier un défaut de fermeture vide. La question n'est pas de savoir comment implémenter la journalisation, ce n'est qu'un exemple.

+1

Quel est le problème avec la façon dont vous l'avez fait? C'est plutôt concis! –

+1

Je ne dis pas que quelque chose ne va pas dans la façon dont je l'ai spécifié. Ce que je ne sais pas, c'est si cette spécification est suffisante et/ou un bon style. – aeisele

Répondre

14

Votre solution est correcte. Vous pouvez introduire un alias de type pour Function1[X, Unit]; utilisez () selon la réponse de Kevin, et laissez tomber les parens inutiles.

scala> type Effect[-A] = (A => Unit) 
defined type alias Effect 

scala> def foo(f: Effect[String] = _ =>()) =() 
foo: (f: (String) => Unit)Unit 

Vous pouvez également définir une fonction noop:

scala> val noop = (a: Any) =>() 
noop: (Any) => Unit = <function1> 

scala> def foo(f: Effect[String] = noop) =() 
6

La valeur () est une instance de l'unité, ce qui devrait faire l'affaire:

def execute(
    goals: List[String], 
    profiles: List[String] = Nil, 
    loggingCallback: (String) => Unit = { _ =>() }): Result = 
{ 
    // method body 
    loggingCallback("a message") 
    // do something returning a Result 
} 

mise à jour

Si quelque chose est facultative, alors il est souvent plus logique de dire explicitement, il en résulte également un meilleur code autodocumenté:

def execute(
    goals: List[String], 
    profiles: List[String] = Nil, 
    loggingCallback: Option[(String) => Unit] = None): Result = 
{ 
    // method body 
    loggingCallback forEach { _.apply("a message") } 
    // do something returning a Result 
} 

mise à jour 2

situations DSL-esque comme celui-ci sont également l'une des situations très peu où je vais fermer les yeux sur l'utilisation de null à Scala:

def execute(
    goals: List[String], 
    profiles: List[String] = Nil, 
    loggingCallback: (String) => Unit = null 
): Result = { 
    // method body 
    val log = Option(loggingCallback) getOrElse {_ =>()} 
    log("a message") 
    // do something returning a Result 
} 

Notez le Option(loggingCallback)-immédiatement convertir le loggingCallback annulable en un bon type sécurisé Option, puis getOrElse pour fournir une alternative de secours.

+0

Vous avez raison l'utilisation de l'option ici rend les choses beaucoup plus claires pour les appelants. – aeisele