/**
* 函数
* 可以像任何其他数据类型一样被传递和操作
*/
object TestFunction {
def main(args: Array[String]): Unit = {
// 先定义一个方法,再定义一个函数,将函数传递到方法
def method2(f:(Int,Int)=>Int) = f(2,3)
val ff = (x:Int,y:Int) => x+y
println(method2(ff) )
// 指定函数参数名
// 参数列表可以不用按顺序传递,直接指定传递
def m(x:Int,y:Int) = x+y
println(m(y=2,x=3))
// 函数,可变参数
// 不需要指定函数参数的个数,可以向函数传入可变长度参数列表
def printStrings( args:String* ) = {
var i : Int = 0;
for( arg <- args ){
println("Arg value[" + i + "] = " + arg );
i = i + 1;
}
}
printStrings("zhangsan","lisi","wangwu")
// 匿名函数
// 使用匿名函数后,我们的代码变得更简洁了
var m1 = (x:Int) => x+1
println(m1(1))
var m2 = (x:Int,y:Int) => x*y-(x+y)
println(m2(2,2))
var m3 = () => 8
println(m3())
// 偏函数
// A代表参数类型,B代表返回类型,常用作输入模式匹配
def func1: PartialFunction[String, Int] = {
case "one" => 1
case "two" => 2
case _ => -1
}
def func2(num: String) : Int = num match {
case "one" => 1
case "two" => 2
case _ => -1
}
// 偏应用函数
// 绑定第一个date参数,第二个参数使用下划线(_)替换缺失的参数列表,并把这个新的函数值的索引的赋给变量
var log = (date:Date,message:String)=>println(date+"----"+message)
var date = new Date
var logWithBound = log(date,_:String)
logWithBound("hhhhhh")
logWithBound("llllll")
logWithBound("kkkkkk")
// 高阶函数
// Scala中允许使用高阶函数, 高阶函数可以使用其他函数作为参数,或者使用函数作为输出结果
// 函数f和值v作为参数,而函数f又调用了参数v
def apply(f: Int => String, v: Int) = f(v)
def iToString[A](x: A) = "[" + x.toString() + 66 + "]"
println( apply(iToString, 10) )
// 函数柯里化
// 柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。
// 新的函数返回一个以原有第二个参数为参数的函数
def add1(x:Int,y:Int) = x+y
println(add1(1,1))
// 柯里化
def add2(x:Int)(y:Int) = x+y
println(add2(1)(1))
// 方法和函数的区别
// 1. 函数可以作为参数传递到方法中,方法不行
val m4 = (x:Int,y:Int) => x-y
def min(f:(Int,Int) => Int,v:Int) = f(10,v)
println(min(m4,5))
// 2. 在Scala中无法直接操作方法,如果要操作方法,必须先将其转换成函数
// 通常情况下编译器会自动将方法转换成函数,例如在一个应该传入函数参数
// 的地方传入了一个方法,编译器会自动将传入的方法转换成函数
def m5(x:Int):Int={
x * 10
}
// 转化
(x:Int) => m5(x)
// 3. 函数必须要有参数列表,而方法可以没有参数列表
def m6 = 100
// val ff = => 100
// 4. 在需要函数的地方,如果传递一个方法,会自动进行ETA展开(把方法转换为函数)
// 5. _将方法转化为函数
def m7(x:Int,y:Int) = x + y
println(m7(1,1))
val f7 = m7 _
println(f7(1,1))
}
}