In Groovy language, it is very simple to check for null
or false
like:
groovy code:
def some = getSomething()
if(some) {
// do something with some as it is not null or emtpy
}
In Groovy if some
is null
or is empty string or is zero number etc. will evaluate to false
. What is similar concise method of testing for null
or false
in Scala?
What is the simple answer to this part of the question assuming some
is simply of Java type String?
Also another even better method in groovy is:
def str = some?.toString()
which means if some
is not null
then the toString
method on some
would be invoked instead of throwing NPE in case some
was null
. What is similar in Scala?
Using pattern matching as suggested in a couple of answers here is a nice approach:
But, a bit verbose.
I prefer to
map
anOption
in the following way:Option(getSomething()) map (something -> doSomethingWith(something))
One liner, short, clear.
The reason to that is Option can be viewed as some kind of collection – some special snowflake of a collection that contains either zero elements or exactly one element of a type and as as you can map a List[A] to a List[B], you can map an Option[A] to an Option[B]. This means that if your instance of Option[A] is defined, i.e. it is Some[A], the result is Some[B], otherwise it is None. It's really powerful!
You could write some wrapper yourself or use an Option type.
I really wouldn't check for
null
though. If there is anull
somewhere, you should fix it and not build checks around it.Building on top of axel22's answer:
Edit: This seems to either crash the compiler or doesn't work. I'll investigate.
Well,
Boolean
cannot benull
, unless passed as a type parameter. The way to handlenull
is to convert it into anOption
, and then use all theOption
stuff. For example:Since Scala is statically type, a thing can't be "a null or is empty string or is zero number etc". You might pass an
Any
which can be any of those things, but then you'd have to match on each type to be able to do anything useful with it anyway. If you find yourself in this situation, you most likely are not doing idiomatic Scala.If you use extempore's null-safe coalescing operator, then you could write your
str
example asIt also allows you to chain without worrying about
null
s (thus "coalescing"):Of course, this answer only addresses the second part of your question.
In Scala, the expressions you described mean that a method called
?
is invoked on an object calledsome
. Regularly, objects don't have a method called?
. You can create your own implicit conversion to an object with a?
method which checks fornull
ness.The above will, in essence, convert any object on which you call the method
?
into the expression on the right hand side of the methodconversion
(which does have the?
method). For example, if you do this:the compiler will detect that a
String
object has no?
method, and rewrite it into:Illustrated in an interpreter (note that you can omit
.
when calling methods on objects):So you could write:
Or you could create an implicit conversion into an object with a
?
method which invokes the specified method on the object if the argument is notnull
- do this:so that you could then write:
Building (recursively) on soc's answer, you can pattern match on
x
in the examples above to refine what?
does depending on the type ofx
. :DWhat you may be missing is that a function like
getSomething
in Scala probably wouldn't return null, empty string or zero number. A function that might return a meaningful value or might not would have as its return anOption
- it would returnSome(meaningfulvalue)
orNone
.You can then check for this and handle the meaningful value with something like
So instead of trying to encode the "failure" value in the return value, Scala has specific support for the common "return something meaningful or indicate failure" case.
Having said that, Scala's interoperable with Java, and Java returns nulls from functions all the time. If
getSomething
is a Java function that returns null, there's a factory object that will make Some or None out of the returned value.So
... which is pretty simple, I claim, and won't go NPE on you.
The other answers are doing interesting and idiomatic things, but that may be more than you need right now.