Avoid using null
Most languages have a special keyword or object to represent that an object reference is "nothing". In Java, it is null. In Java, null is a keyword, not an object, so calling any method on it is illegal. But this is a confusing choice for language designers. Why return a keyword when the programmer expects to return an object?
Scala's Option type
In order to make the goal that everything is an object more consistent, and to follow functional programming conventions, Scala encourages you to use the Option type when variables and function return values may not reference any value. When there is no value, use None, which is a subclass of Option. If there is a value to reference, use Some to contain that value. Some is also a subclass of Option. None is declared as an object, not a class, because we only need one instance of it. In this way, it is somewhat like the null keyword, but it is a real object with methods.
Application examples
Values of type Option are often used as return types of operations on Scala collection types (List, Map, etc.). For example, the get method of Map:
scala> val capitals = Map("France"->"Paris", "Japan"->"Tokyo", "China"->"Beijing")
capitals: scala.collection.immutable.Map[String,String] = Map(France -> Paris, Japan -> Tokyo, China -> Beijing)
scala> capitals get "France"
res0: Option[String] = Some(Paris)
scala> capitals get "North Pole"
res1: Option[String] = None
Option has two subcategories, Some and None. When the program returns Some, it means the function has successfully given you a String, and you can get that String through the get() function. If the program returns None, it means there is no string for you.
When it returns None, that is, when there is no String for you, if you still insist on calling get() to obtain the String, Scala will also throw a NoSuchElementException to you. We can also choose another method, getOrElse. This method returns the corresponding value when the Option is an instance of Some, and returns the passed-in parameter when it is an instance of None. In other words, the parameter passed to getOrElse is actually the default return value.scala> capitals get "North Pole" get warning: there was one feature warning; re-run with -feature for details java.util.NoSuchElementException: None.get at scala.None$.get(Option.scala:347) at scala.None$.get(Option.scala:345) ... 33 elided scala> capitals get "France" get warning: there was one feature warning; re-run with -feature for details res3: String = Paris scala> (capitals get "North Pole") getOrElse "Oops" res7: String = Oops scala> capitals get "France" getOrElse "Oops" res8: String = Paris
Separate the optional value through pattern matching. If the matched value is Some, extract the value inside Some and assign it to variable x:
def showCapital(x: Option[String]) = x match {
case Some(s) => s
case None => "?"
}
Tips
Scala programs use Option very frequently. In Java, null is used to represent empty values, and null keyword checks have to be added in many places in the code, otherwise NullPointerException can easily occur. Therefore, Java programs need to be concerned about which variables may be null. The possibility of these variables being null is very low, but once it happens, it is difficult to find out why a NullPointerException occurred. Scala's Option type can avoid this situation, so Scala applications recommend using the Option type to represent some optional values. With the Option type, readers can see at a glance that values of this type may be None.
Actually, thanks to Scala's static typing, you cannot mistakenly try to call a method on a value that may be null. Although this is an easy mistake to make in Java, it fails to compile in Scala. This is because the programming practice of not checking whether a variable is null in Java becomes a type error in Scala (you cannot use Option[String] as String). Therefore, the use of Option strongly encourages more flexible programming habits.
Detailed explanation of Option[T]
In Scala, Option[T] is actually a container, just like an array or a List. You can think of it as a List that may have zero or one element.
When your Option has something in it, the length of this List is 1 (that is, Some), and when your Option has nothing in it, its length is 0 (that is, None).
for loop
If we use Option as an ordinary List and use a for loop to iterate over this Option, then if the Option is None, the code in the for loop will naturally not execute, and thus we achieve the goal of "not having to check whether the Option is None".
scala> val map1 = Map("key1" -> "value1")
map1: scala.collection.immutable.Map[String,String] = Map(key1 -> value1)
scala> val value1 = map1.get("key1")
value1: Option[String] = Some(value1)
scala> val value2 = map1.get("key2")
value2: Option[String] = None
scala> def printContentLength(x: Option[String]) {
| for (c <- x){
| println(c.length)
| }
| }
printContentLength: (x: Option[String])Unit
scala> printContentLength(value1)
6
scala> printContentLength(value2)
map operation
One of the core concepts in functional programming is transformation, so most languages that support functional programming support an operation called map(). This operation can help you apply some actions to the contents of a container and turn it into another new container.
Now let's consider how to use Option's map method to implementlength: xxxThe output form is:
First calculate the length of the string inside the Option container
Then add the text "length: " in front of the length
Finally, iterate through the container once and print out what is inside it.
scala> value1.map(_.length).map("length: " + _).foreach(println)
length: 6
scala> value1.map("length: " + _.length).foreach(println)
length: 6
Through this "transformation" method, we can also achieve the desired effect, and likewise we don't need to make a judgment about "whether it is None".
Original link: https://www.jianshu.com/p/95896d06a94d