Scala closure anonymous Functions

Source: Internet
Author: User

The name of a function language comes from the concept that the program behavior should be like a mathematical function; in other words, given a set of inputs, the function should always return the same output. This not only means that each function must return a value, but also means that from one call to the next call, the function must not have an intrinsic State in nature ). This kind of stateless concept (in the function/object field, it is always an object by default ), it is the main reason why function language is regarded as the greatest "Savior" in the field of concurrency.

As a level-1 concept, closure functions must be recognized as separate structures, also known as closures, which have been a hot topic in the Java Community recently. In Scala, this is easy to complete. Consider the program in listing 3. This program defines a function that calls another function every second:


Listing 3. timer1.scala

Object Timer

{

Def oncepersecond (): unit =

{

While (true)

{

System. Out. println ("Time flies when you're having fun (ctionally )...")

Thread. Sleep (1000)

}

}


Def main (ARGs: array [String]): unit =

{

Oncepersecond

}

}



Unfortunately, this special code has no function ...... Or it is useless. For example, if you want to change the displayed message, you must modify the subject of the oncepersecond method. Traditional Java programmers define the string parameter for oncepersecond to include the message to be displayed. However, this is even an extreme restriction: Any other periodic task (such as ping a remote server) will require their own version of oncepersecond, which is a clear violation
Do not repeat yourself. I think I can do better.

Listing 4. timer2.scala

Object Timer

{

Def oncepersecond (callback: () => unit): unit =

{

While (true)

{

Callback ()

Thread. Sleep (1000)

}

}


Def timeflies (): unit =

{Console. println ("Time flies when you're having fun (ctionally )...");}


Def main (ARGs: array [String]): unit =

{

Oncepersecond (timeflies)

}

}



Now, things are getting interesting. In Listing 4, The oncepersecond function accepts a parameter, but its type is unfamiliar. Formally, a parameter named callback accepts a function as a parameter. This function can be used as long as the input function does not accept any parameter (indicated by () and does not return (indicated by =>) values (indicated by the function value unit. Note that in the loop body, I use callback to call the passed Parameter Function object.

Fortunately, I already have a function named timeflies elsewhere in the program. Therefore, I pass it to the oncepersecond function from main. (You will also notice that timeflies uses a Scala-introduced class console, Which is used the same as system. out or the new java. Io. Console class. This is purely an aesthetic problem; system. out or con

Anonymous function. What is your function?

Now, this timeflies function seems a waste-after all, it is useless except to pass it to the oncepersecond function. Therefore, I will not officially define it, as shown in listing 5:

Listing 5. timer3.scala

Object Timer

{

Def oncepersecond (callback: () => unit): unit =

{

While (true)

{

Callback ()

Thread. Sleep (1000)

}

}


Def main (ARGs: array [String]): unit =

{

Oncepersecond () =>

Console. println ("Time flies... Oh, you get the idea ."))

}

}


In listing 5, the main function passes an arbitrary piece of code as a parameter to oncepersecond, which looks like a Lambda expression from Lisp or scheme. In fact, this is another closure. This anonymous function once again demonstrates the powerful feature of processing a function as a level-1 citizen. It allows you to completely generalize code beyond inheritance. (Fans of the strategy model may have begun to spam .)

In fact, oncepersecond is still very special: It has unrealistic limitations, that is, the callback will be called every second. I can generalize a function by accepting the second parameter and specifying the frequency of calling the passed function, as shown in Listing 6:

Listing 6. timer4.scala

Object Timer

{

Def periodiccall (seconds: int, callback: () => unit): unit =

{

While (true)

{

Callback ()

Thread. Sleep (seconds * 1000)

}

}


Def main (ARGs: array [String]): unit =

{

Periodiccall (1, () =>

Console. println ("Time flies... Oh, you get the idea ."))

}

}


This is a common topic in the function language: create an advanced abstract function that only performs one thing, let it accept a code block (anonymous function) as a parameter, and call this code block from this advanced function. For example, traverse an object set. You do not need to use traditional Java iterator objects in the for loop, instead, use a function library to define a function in the Collection class-usually called "ITER" or "map"-to accept a function with a single parameter (the object to be iterated. For example, the above array class has a function filter, which is in the list
7:

Listing 7. partial listing of array. Scala

Class array [A]

{

//...

Def filter (P: (a) => Boolean): array [a] =... // not shown

}



Listing 7 declares that p is a function that accepts generic parameters specified by a and returns a Boolean value. Scala documentation indicates that the filter "returns an array consisting of all elements that meet the predicate P ". This means that if I want to return my hello World Program and look for all the command line parameters starting with the letter G, I can write the code as simple as listing 8:

Listing 8. Hello, G-men!

Object helloworld

{

Def main (ARGs: array [String]): unit = {

Args. Filter (Arg: string) => Arg. startswith ("G "))

. Foreach (Arg: string) => console. println ("found" + Arg ))

}

}



Here, the filter accepts the predicate. This is an anonymous function that implicitly returns the result of the call to the Boolean value (startswith () and calls the predicate using each element in args. If the predicate returns true, it adds this value to the result array. After traversing the entire array, it accepts the result array and returns it, and then the array is immediately used as "foreach"
The source of the call. The operation executed by this call is like the meaning of its name: foreach accepts another function and applies this function to each element in the array (in this example, only show each element ).

It is not hard to imagine what the preceding hellog. Scala Java is like, and it is not hard to find that the scala version is very short and clear.

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.