web-dev-qa-db-fra.com

Comment vérifier null dans une seule instruction dans scala?

Dans mon code scala:

QueueManager.add(getObject)

getObject est une méthode qui renvoie un objet de type QueueObject.

def getObject : QueuObject = {
    val response = //some response
    return response
}

Existe-t-il un moyen de vérifier que la réponse est nulle, tout en ajoutant le QueueObject? Je sais que je peux le faire:

if (getObject != null)
    QueueManager.add(getObject)

Mais je ne souhaite pas ajouter un niveau d'indentation. Y a-t-il un opérateur qui fait cela en ligne?

Merci.

43
theTuxRacer

Essayez d'éviter d'utiliser null dans Scala. Il n'est vraiment là que pour l'interopérabilité avec Java. Dans Scala, utilisez Option pour les éléments qui peuvent être vides. Si vous appelez une méthode API Java qui pourrait retourner null, enveloppez-la immédiatement dans un Option.

def getObject : Option[QueueObject] = {
  // Wrap the Java result in an Option (this will become a Some or a None)
  Option(someJavaObject.getResponse)
}

Remarque: Vous n'avez pas besoin de le mettre dans une val ou d'utiliser une instruction explicite return dans Scala; le résultat sera la valeur de la dernière expression du bloc (en fait, puisqu'il n'y a qu'une seule instruction, vous n'avez même pas besoin d'un bloc).

def getObject : Option[QueueObject] = Option(someJavaObject.getResponse)

Outre ce que les autres ont déjà montré (par exemple en appelant foreach sur le Option, ce qui peut être légèrement déroutant), vous pouvez également appeler map dessus (et ignorer le résultat de l'opération de carte si vous n'en avez pas besoin):

getObject map QueueManager.add

Cela ne fera rien si le Option est un None, et appellera QueueManager.add s'il s'agit d'un Some.

Je trouve que l'utilisation d'un if régulier est cependant plus claire et plus simple que l'utilisation de n'importe laquelle de ces "astuces" juste pour éviter un niveau d'indentation. Vous pouvez également l'écrire sur une seule ligne:

if (getObject.isDefined) QueueManager.add(getObject.get)

ou, si vous voulez traiter avec null au lieu d'utiliser Option:

if (getObject != null) QueueManager.add(getObject)

edit - Ben a raison, attention à ne pas appeler getObject plus d'une fois s'il a des effets secondaires; mieux l'écrire comme ceci:

val result = getObject
if (result.isDefined) QueueManager.add(result.get)

ou:

val result = getObject
if (result != null) QueueManager.add(result)
71
Jesper
Option(getObject) foreach (QueueManager add)
12
Daniel C. Sobral

S'il renvoyait à la place Option[QueueObject], Vous pourriez utiliser une construction comme getObject.foreach { QueueManager.add }. Vous pouvez l'encapsuler directement en ligne avec Option(getObject).foreach ... car Option[QueueObject](null) est None.

12
Ben Jackson

Bien que je sois sûr que la réponse de @Ben Jackson avec Option(getObject).foreach est la manière préférée de le faire, j'aime utiliser un AnyRef pimp qui me permet d'écrire:

getObject ifNotNull ( QueueManager.add(_) )

Je trouve que ça se lit mieux.

Et, d'une manière plus générale, j'écris parfois

val returnVal = getObject ifNotNull { obj =>
  returnSomethingFrom(obj)
} otherwise {
  returnSomethingElse
}

... en remplaçant ifNotNull par ifSome si j'ai affaire à un Option. Je trouve cela plus clair que d'envelopper d'abord une option, puis de le faire correspondre à un motif.

(Pour l'implémentation, voir Implémentation de ifTrue, ifFalse, ifSome, ifNone, etc. dans Scala pour éviter if (...) et la simple correspondance de modèle et le Otherwise0/Otherwise1 Des classes.)

7