Scala study notes (VI): Functions

1. The most common way is defined as a member function of an object, such functions are called methods

 

2. Local function or local function - to other functions of the function definition

The scope of local functions and local variable scope as

Visiting a local function parameters of the function is a common use of nested functions

import scala.io.Source
object LongLines {
  def processFile(filename: String, width: Int) {
    def processLine(line:String){
     if(line.length > width)
       println(filename + ":" +line.trim)
   }
    val source= Source.fromFile(filename)
    for (line <- source.getLines())
      processLine(line)
   }
}

 

3. Name parameter - specified parameter name

Under normal circumstances, the argument list of one-time incoming call the function parameters and function definitions.

scala> def  speed(distance: Float, time: Float): Float = distance/time
speed: (distance: Float, time: Float)Float
scala> speed(100,10)
res0: Float = 10.0

Named parameters allows the parameters passed in any order

scala> speed(time=10, distance=100)
res1: Float = 10.0

 

4. The default parameters

Scala defining a function that allows a default value of the specified parameter, thereby allowing the function is called may not specify the parameters, and then uses its default value.

The default parameters are usually with the use of named parameters

scala> def printTime(out:java.io.PrintStream = Console.out, divisor:Int =1 ) =
     | out.println("time = " + System.currentTimeMillis()/divisor)
printTime: (out: java.io.PrintStream, divisor: Int)Unit
The scala> Print Time () 
Time = 1383220409463 
scala> Print Time (divisor = 1000 ), 
time = 1383220422

 

5. vararg

Scala allows one parameter may specify the last repeat (variable length parameter) defining a function, thereby allowing the caller of the function using a variable argument list to call the function

Scala using the "*" indicates the parameter is a parameter repeat

E.g:

def echo(args:String*)=
  for(arg<-args) println(arg)
echo("here")
echo("here","there")

Type variable length parameter is an array

String * on the type of practical embodiment of Array [String], however, if a direct array type parameters passed to this function, the compiler will complain

 

To avoid this, you can add after the variable _ *

This symbol tells the Scala compiler individually for each element in the array passed to pass parameters

 

6. function parameters

def filesMatching( query: String, matcher: (String, String) => Boolean) = {
    for(file <- filesHere; if matcher(file.getName, query))
      yield file
}

Second parameter matcher herein filesMatching function is a function, it will match any type String [two parameters, and the return value of type Boolean function]

Thus the above-described function can function as a common, example:

def filesEnding(query:String) =
   filesMatching(query, _.endsWith(_))
def filesContaining(query:String)=
   filesMatching(query, _.contains(_))

 

Extended:

The use of closure, the above code can be further simplified

object FileMatcher {
  private def filesHere = (new java.io.File(".")).listFiles

  def filesMatching(matcher: (String) => Boolean) = {
    for (file <- filesHere; if matcher(file.getName))
      yield file
  }

  def filesEnding(query: String) =
    filesMatching(_.endsWith(query))

  def filesContaining(query: String) = filesMatching(_.contains(query)) def filesRegex(query: String) = filesMatching(_.matches(query)) }

 

7. tail recursion

If the last line is a function call itself, to put this recursion is called tail-recursive

Scala compiler can detect tail recursion, optimization will do, and thus instead of using a loop

 

You can add scalac compiler parameters -g: notailcalls to cancel this optimization, after which, if an exception is thrown, tail-recursive call stack will be a multi-layer display

 

8. function literal

The written anonymous function literals

(x :Int ) => x +1

The above example => symbol indicates that the function converts symbols into something something left to the right of the symbol

 

You can use it as a transfer to another function or value assigned to the other variables, examples:

var increase = (x :Int ) => x +1
increase(10)

 

Many libraries and allows Scala as a function of parameters such as filter foreach methods or method, as follows:

args.foreach((x:Int) => println(x))
val numbers = List ( -1, -12, 5, 0, -5, 1)
numbers.filter(x => x > 0)

 

Note: literal function (x: Int) => x + 1 Scala internally represented as an object class with a parameter of Function1

N FunctionN function represents a function with argument, Function0 representatives without parameters

 

If the function definition requires multiple statements, {} may be used, such as:

var increase = (x :Int ) => {
  println("We")
  println("are")
  println("here")
  x + 1
}

 

Format short literal function

Scala allowed "placeholder" or underscore ( "_") instead of one or more parameters, if the parameters appear only once in the function definition, the compiler can infer Scala Parameter Type

val numbers = List ( -11, -10, - 5, 0, 5, 10)
numbers.filter(_ > 0)

 

The following code parameters need to specify the type of _

val f=(_:Int)+(_:Int)
f(1,2)

 

9. The partial application function

In Scala, when you call the function, passing the required parameters, the function is to "apply" to the parameter.

Part of the application function means: When calling a function, does not specify all the parameters required for the function, thus creating a new function, this new function is called partial application function of the original function

def sum = (_:Int) + (_ :Int) + (_ :Int)

In response to these codes, a fixed first and third parameters

scala> val b = sum(1, _ :Int, 3)
b: Int => Int = <function1>
scala> b(2)
res1: Int = 6

The Function1 variable b of type (a function with a parameter), which is applied by the sum of the first and third parameters thereof.

Call b (2), is actually called sum (1,2,3).

 

In fact, in some cases, you can use "_" instead of the entire list

numbers.foreach(println _)

 

In Scala, if a defined portion of the application function and all the parameters can be omitted, the underscore "_" is omitted

numbers.foreach(println)

 

10. "currying"

Use "Curry" technology can use the original function of a list of parameters as a function of conversion using a plurality of parameter list

scala> def plainOldSum(x:Int,y:Int) = x + y
plainOldSum: (x: Int, y: Int)Int
scala> plainOldSum(1,2)
res0: Int = 3

Conversion: The parameters a parameter list into two lists, each list containing a parameter

scala> def curriedSum(x:Int)(y:Int) = x + y
curriedSum: (x: Int)(y: Int)Int

This function takes two arguments list, call as follows:

scala> curriedSum (1)(2)
res0: Int = 3

When calling curriedSum (1) (2) when, in fact, two ordinary function call sequentially, first call parameters and returns a value x of a function type, the function values ​​of the second call returned parameter y

 

scala> val onePlus = curriedSum(1)_
onePlus: Int => Int = <function1>

Underscore ( "_") as a second parameter list placeholders

scala> onePlus(2)
res2: Int = 3

 

11.

In Scala, if the function of only one parameter can be used instead of {} ()

scala> println ("Hello,World")
Hello,World
scala> println { "Hello,world" }
Hello,world

 

If the function uses two parameters, can not be replaced with {} ()

def withPrintWriter (file: File, op: PrintWriter => Unit) {
  val writer=new PrintWriter(file)
  try{
    op(writer)
  }finally{
    writer.close()
  }
}

 

But if you use "currying" re-defined function, there is such a possibility

import scala.io._
import java.io._
def withPrintWriter (file: File)( op: PrintWriter => Unit) {
  val writer=new PrintWriter(file)
  try{
    op(writer)
  }finally{
    writer.close()
  }
}

transfer:

val file = new File("date.txt")
withPrintWriter(file){
  writer => writer.println(new java.util.Date)
}

Written above code is similar in Scala if, while the built-in grammar, etc.

if(x > y) {
  x += 1
}

 

12. The operation is repeated for the optimization

scala> def twice (op:Double => Double, x:Double) =op(op(x))
twice: (op: Double => Double, x: Double)Double
scala> twice(_ + 1, 5)
res0: Double = 7.0

 

13. parameters by name

 

Guess you like

Origin www.cnblogs.com/studyLog-share/p/4788310.html