Suppose I have String parameter coming from a query string request parameters. As you know the parameter may be missing or may be there but value is empty string. In groovy language I can simply d开发者_运维问答o something like
List lst = words?.split(',')
if words was null, lst would be null instead of throwing NPE
what is similar shortcut in scala?
Option[String] is not an option here as words is of type String as it is coming from query string.
If you want to keep nulls around,
val lst = Option(words).map(_ split ',').orNull
But what you should do is get rid of the nulls. If some API (Java, most likely) may return a null
, wrap its call in Option()
, to get a proper Option
instead. If some API needs to be passed a null
, pass it an option.orNull
.
Inside your own code, don't let anything be null
.
I would still use Option
here. You can easily convert a potentially null variable into an Option
using the Option
object. e.g.
scala> def splitter(s: String) = Option(s) map { _.split(',') }
splitter: (s: String)Option[Array[String]]
scala> splitter("Here, are, some, strings, man.")
res50: Option[Array[String]] = Some([Ljava.lang.String;@7f4613f1)
scala> splitter(null)
res51: Option[Array[String]] = None
An empty String already returns an empty List - well - Array:
scala> "".split (',')
res59: Array[String] = Array()
returning null is possible:
scala> val lst = if (words == null) null else words.split (',')
lst: Array[String] = Array()
but in most cases, an empty List would be better, wouldn't it?
scala> val lst = if (words == null) Array () else words.split (',')
lst: Array[_ <: String] = Array()
There is no direct equivalent to the ?.
operator in Scala.
The most concise implementation in Scala without introducing other symbols would probably be
val lst = if( words == null ) Nil else words.split(',')
or, leading up to the improvement below,
val lst = (if( words == null ) "" else words).split(',')
In Scala the general design rule is to avoid null values whenever possible, either through the use of Option[] or (as also in Java) through the use of singleton fallback values (here "", although Option is the preferred way).
But since you're apparently locked into using an API that does return null values, you can define a little helper function to wrap the API results. You can try the "fallback object" route with something like this:
def safe(s:String) : String = if( s == null ) "" else s
val lst = safe( words ).split(',')
or, a bit more verbose, with Option[]:
def safe(s:String) : Option[String] = if( s == null ) None else Some(s)
val lst = safe( words ) match { case None => Nil; case Some( w ) => w.split(',') }
精彩评论