score:206
The Option
companion object's apply
method serves as a conversion function from nullable references:
scala> Option(null)
res4: Option[Null] = None
scala> Option(3)
res5: Option[Int] = Some(3)
score:-2
This is a very old topic but a nice one!
It's true that converting any Non-exception result of Try to Option will result in a Some...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
...because Try is not about nullability checking but just a way to functionally handle exceptions.
Using Try to catch an exception and converting that to an Option for convenience will only show None in case an exception happens.
scala> Try(1/0).toOption
res11: Option[Int] = None
You want to preserve the values that come out of Try. That may be null.
But it is also true that the standard lib is quite confusing sometimes...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
This behaviour is a bit inconsistent but it kind of reflects the intented usage of both Try and Option.
You use try to get whatever comes out of an expression that may throw exceptions, and you don't care about the exception itself.
The value that may come out may very well be a null. If toOption gave None, you could not differenciate between an exception and a null, and that is not pretty!
Standalone, you use Option to encapsulate the existence or not of something. So in that case Some(null) is None, and that makes sense, because null in that case represents the absence of something. There's no ambiguity here.
It's important to remark that in any case referencial transparency is not broken since .toOption is not the same as Option()
If you really need to enforce BOTH exception safety AND null safety, and your code really really doesn't need to differenciate between null and an exception, you just need to combine both paradigms! Because well, that's what you want, right?
You can do it in one way...
scala> Try(Option(null)).getOrElse(None)
res23: Option[Null] = None
scala> Try(Option(3/0)).getOrElse(None)
res24: Option[Int] = None
scala> Try(Option(3)).getOrElse(None)
res25: Option[Int] = Some(3)
... or another ...
scala> Try(Option(null)).toOption.flatten
res26: Option[Null] = None
scala> Try(Option(3/0)).toOption.flatten
res27: Option[Int] = None
scala> Try(Option(3)).toOption.flatten
res28: Option[Int] = Some(3)
... or the ridiculously ugliest of them anothers ...
scala> Option(Try(null).getOrElse(null))
res29: Option[Null] = None
scala> Option(Try(3/0).getOrElse(null))
res30: Option[Any] = None
scala> Option(Try(3).getOrElse(null))
res31: Option[Any] = Some(3)
score:5
Notice that when working with Java objects it won't work as expected:
val nullValueInteger : java.lang.Integer = null
val option: Option[Int] = Option(nullValueInteger)
println(option) // Doesn't work - zero value on conversion
val nullStringValue : String = null
val optionString: Option[String] = Option(nullStringValue)
println(optionString) // Works - None value
score:20
The Option
object has an apply
method that does exactly that:
var myOptionalString = Option(session.get("foo"));
Source: stackoverflow.com
Related Query
- Wrapping null-returning method in Java with Option in Scala?
- Returning a java List with a scala method
- Why wrapping a generic method call with Option defers ClassCastException?
- Calling Java vararg method from Scala with primitives
- Method call with option value or default parameter in Scala
- Calling Java API from Scala with null argument
- Is it possible to write a method in Scala returning objects with different type parameter?
- Override Java method with arg Class<?> in Scala
- Returning typed collection from Scala 2.13 method to Java 8 caller
- How to look up the type of a method returning a type parameter with scala reflection?
- Overriding abstract method of Java class in Scala with bounded inheritence
- How to implement Java method returning a generic type parametrized with array in Scala?
- scala overrides java class method with inner class and type parameters
- Scala Option vs Java null
- Overriding java method with arg of type java.util.Map[String, String] in scala class
- Scala calling Java method with array parameter
- AbstractMethodError when overriding a Java method with vararg parameter from Scala
- Get method parameters with specific annotation in aspect in scala using java reflection
- How to make covariant in scala a java generic method with a parameterized return type
- Calling a Java static method with generics from Scala
- How to create a Scala Jdbc program using Option to handle null while returning connection?
- Convert method override with wildcard from Java to Scala
- Scala interop with Java overriding method with Object
- Call Java method with alternatives from Scala
- to_timestamp with spark scala is returning null
- Access inner class method with "fine" syntax in Java using Scala class & object
- Equivalent in scala to java static method with type parameters
- Calling a Java method (dealing with generics) from Scala failed
- What's the standard way to work with dates and times in Scala? Should I use Java types or there are native Scala alternatives?
- Using Scala traits with implemented methods in Java
More Query from same tag
- Scala behaviour when assigning literals or variables to Char
- Scala Generics, exclude type
- What does the @elidable annotation do in Scala, and when should I use it?
- How to modify the csv feed file in gatling
- Scala Map Transformation
- class type error while working with generic method in scala
- Scala/Slick JDBC encoding configuration with typesafe config
- In scala, why Range.hashCode() is so slow and cannot be made faster?
- Is actually possible to deprecate Scala case class fields?
- How can I make this Scala function (a "flatMap" variant) tail recursive?
- Spark & Scala: Read in CSV file as DataFrame / Dataset
- scala.MatchError: null on scala
- How to read data from Kafka topic in Scala
- How do I parse DBObject to case class object using subset2?
- Scala Lift - Reading a file from "/resources/toserve"
- How to run a function every 3 seconds in Play scala?
- changing form action with play 2.0
- substitution model scala
- Scala: return based on value of int expression
- Generic strongly-typed scala method to retrieve item of a particular type from a collection
- How can I remove an RDD from a DStream in Spark Streaming?
- Marshalling in Akka HTTP
- Can Scala select a concrete implicit when mapping a list of concrete objects inheriting a common trait?
- Using Cats Show on enum
- Cannot modify Seq.head
- Strongly typed form fields in Play Framework views
- Scala: Print Double with decimal and thousands seperator and 2 decimal places
- Scala equivalent of combining generic types in Java?
- more on type parameters for scala, trying to get a consistent reference to a type
- How can I execute multiple tasks in Scala?