Desugar Scala (17) -- Option and for, and what happens in your mind

Source: Internet
Author: User

Desugar Scala (17) -- Option and for, and what happens in your mind

 

 

The for keyword in Scala is very interesting. It can be used to write multi-layer nested for loop into one layer. For example:

1
for(i<-1 to 10;j<-1 to 10;k<-1 to 10) yield(s$i $j $k)

The result of executing this line of code is as follows:

12345678910111213141516171819202122
1 1 11 1 21 1 31 1 41 1 51 1 61 1 71 1 81 1 91 1 101 2 11 2 21 2 31 2 41 2 51 2 61 2 71 2 81 2 91 2 10............

In this way, you can use a line of code to write the effect of a three-tier loop. The code looks very compact and has little noise.

But today we are not talking about this for, but about how it works with Option.

Option itself is an abstract class that represents a value that may or may not exist (who's meow ?). It has two implementation classes, Some and None. As the name implies, Some indicates a value, and None indicates no.

In fact, the above statement is not accurate enough. Some is an implementation class, while None is actually a Singleton, but this does not affect the subsequent content.

Now imagine a very simple scenario where the unit price and quantity are used to calculate the total price, and the unit price and quantity may not be obtained, the code will probably be like this:

12345678910
  def calculateTotal: Option[Int] = {    val price: Option[Int] = getPrice    val amount: Option[Int] = getAmount    if (price.isEmpty || amount.isEmpty) {      None    } else {      Some(price.get * amount.get)    }  }

Both getPrice and getAmount return an Option [Int], just like an Integer in Java that can be null. The calculated total price is also an Option [Int], which may or may not exist.

In this Code, check whether the unit price and quantity exist. If either of them does not exist, return None, indicating that the total price cannot be obtained. If both of them exist, the product of the two will be returned with Some packets.

This code looks okay, it is a common method, but it is a little cool. If you use for, you can greatly simplify this Code:

123
  def calculateTotalWithFor: Option[Int] = {    for (price <- getPrice; amount <- getAmount) yield price * amount  }

This method has only one line, and its implementation behavior is exactly the same as the above Code.

This is amazing. You don't have to judge whether the price and quantity exist, or decide whether to return None or Some based on the judgment result. How does it work?

Let's take a look at the decompilation results:

1234567891011121314151617
public Option calculateTotalWithFor() {    return getPrice().flatMap(new AbstractFunction1() {        public final Option apply(final int price) {            return OptionAndFor..MODULE$.account$of$OptionAndFor$$getAmount().map(new AbstractFunction1.mcII.sp() {                private final int price$1;                public final int apply(int amount) {                    return apply$mcII$sp(amount);                }                public int apply$mcII$sp(int amount) {                    return price * amount;                }            });        }    });}

The results of this decompilation are hard to read, but we can still see a rough picture. It first calls flatMap for the returned value of getPrice and passes it an anonymous function (AbstractFunction1). In this anonymous function, map is called for the returned value of getAmount, an anonymous function is also introduced to it, and then a multiplication operation is performed in the second-layer anonymous function.

If Scala is used to express it, it is like this:

123
  def calculateTotalWithFlatMapAndMap: Option[Int] = {    getPrice.flatMap(price => getAmount.map(amount => amount * price))  }

It can be seen that the magic of the for code above is that it uses the flatMap and map methods of Option.

These two methods share one feature: if the current Option instance of the called flatMap or map is None, the incoming anonymous function is ignored and the None is directly returned.

This is easy to understand. If one of the members involved in the operation is None, you don't have to worry about what the remaining members are, the final calculation result is None. This is consistent with the logic of the code written with the | Operator.

So far, we have stripped our clothes for the combination of Option and for. It uses the flatMap and map of Option to implement Compact code.

The magic is not only the shorter code, but also the improved signal-to-noise ratio, which provides us with a simpler thinking model.

What happened in our mind when we first wrote or read the code using if else?

1. to get the price and quantity 2. to determine whether the price is blank, you must determine whether the quantity is blank (which is less related to the business and belongs to the technical category) 3. if any one is blank, the result is blank (less associated with the business, and belongs to the technical category) 4. if neither of them is null, perform the multiplication operation.

What do you think in your mind when writing or reading the for code?

1. Get the price and quantity 2. Perform Multiplication

The purpose of writing this code is to express the business logic and transmit business-related information to future code readers.

Null Value Judgment is biased. If this code is eliminated, the information we pass to other programmers will contain less noise unrelated to the business. In addition, we do not need to consider so many things in our minds when writing them on our own.

It is good for you and others. This is really a wonderful language feature.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.