闭包
- 如下 addMore 成为一个“闭包”。因为它引用到函数外面定义的变量。定义这个函数的过程,是将和这个自由变量捕获二构成一个封闭的函数。
scala> var more =1
more: Int = 1
scala> val addMore = (x:Int) => x + more
addMore: Int => Int = <function1>
scala> addMore (100)
res1: Int = 101
scala> more = 9999
more: Int = 9999
scala> addMore ( 10)
res2: Int = 10009
可变参数
- Scala中使用
*
来知名该参数为重复参数
scala> def echo (args: Any *) =
| for (arg <- args) println(arg)
echo: (args: Any*)Unit
scala> val arr = Array("java","scala","python")
arr: Array[String] = Array(java,scala,python)
scala> echo ("Hello",123,true,arr)
Hello
123
true
[Ljava.lang.String;@2c282004
- 若要只传入数组的值,可用以下方法
scala> echo(arr: _*)
命名参数
- 顾名思义 就是在调用函数时,参数传入和函数定义刘表是一一对应,允许使用任意顺序。如下:
scala> def add(one: Double, two: Double) :Double = one + tow
add: (one: Double, two: Double) Double
scala> add(two=10, one=2)
res1: Double = 12.0
高阶函数
- 函数的参数也可以是另一个函数
val arr = Array("javaisgood", "thisscala", " 123456")
def strMatcher(matcher: (String) => Boolean) = {
for(str <- arr; if matcher(str))
yield str
}
def strEnding(str: String) = strMatcher(_.endsWith(str))
def strContaining(str: String) = strMatcher(_.contains(str))
def strRegex(str: String) = strMatcher(_.matches(str))
柯里化函数
- 柯里化是把接收多个参数变换成接收一个单一参数(最初函数的第一个参数)的函数,返回接收余下的参数而且返回结果的新函数的技术。
// common function
def add(x: Int, y: Int) = {
println("x: " + x)
println("y: " + y)
x + y
}
//curry function
def _add(x: Int)(y:Int) = {
println("_x: " + x)
println("_y: " + y)
x + y
}
// split
def first(x: Int) = (y: Int) => {
println("__x: " + x)
println("__y: " + y)
x + y
}
first: (x: Int)Int => Int
scala> val second=first(1)
second: Int => Int = <function1>
scala> second(2)
res1: Int = 3
scala> val onePlus = _add(1)_
onePlus: Int => Int = <function1>
- 其中
_
作为第二参数列表的占位符
Call By Name & Call By Value
Call by value(传值调用)
使用 (变量 :类型)
Call by name(传名调用)
使用 (变量 : => 类型)
注意 ":" 和 "=>"之间一定要有空格
def main(args: Array[String]) {
// testOne
testCallByNameAndValue(1,testLoop(6))
// testTwo
testCallByNameAndValue(testLoop(6),1)
}
// x为传值调用,y为传名调用
def testCallByNameAndValue(x: Int,y: => Int) = {
println("scala")
1
}
def testLoop(a: Int):Int = {
for (i <- (0 until a)) println("Iteration" + i)
1
}
// results of execution
// testOne
scala
// testTwo
Iteration0
Iteration1
Iteration2
Iteration3
Iteration4
Iteration5
scala
总结:
Call By Value :无论方法是否使用该参数都要先将该参数的值计算出来再传入
Call By Name :只有在该参数被方法使用时才计算该参数的值
定义新的的控制结构
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
- 在Scala中,如果调用的函数只有一个参数,可以使用
{}
来代替()
网友评论