函数的传值调用和传名调用
/***
* 传值调用 和 传名调用
* 函数可以作为参数传递到方法里面
*/
package day01
object callByname {
var money = 100
def huaQian(): Unit ={
money = money - 5;
}
def shuQian(): Int ={
huaQian()
money
}
def add(a: Int => Int,b: Int): Int ={
a(b)+ b
}
// x: =>Int 表示的是一个方法的签名 =》没有参数,返回值为Int类型的函数
// x相当于一个函数的引用,或者可以理解为函数名
def printByName(x: =>Int) = {
for(b <- 0 to 3){
println(s"每次都算算还剩:${x}元")
}
}
def printByValue(x: Int) ={
for(b <- 0 to 3){
println(s"测试:${x}元")
}
}
def main(args: Array[String]): Unit = {
//传名调用
//将shuQian方法名称传递到方法的内部执行
//printByName(shuQian())
//传值调用 printByValue 参数为一个具体的数值
//1.计算shuQian 的返回值
//2.将返回值作为参数传入printByValue
//printByValue(shuQian())
val f1 = (a: Int) => a * 10
val r1 = add(f1,2)
println(r1)
val arr = Array(0,1,2,3)
val arr1 = arr.map(f1) //map 函数参数为f: Int => B 这里的B根据你传入的函数的返回类型 而定。
//假如你传入的函数返回类型为 Int,则B 为Int
val arr2 = arr.map(f1(_)) //同上
println(arr1.toBuffer)
}
}
可变参数 和 默认参数
package day02
object ManyPrames {
/***
*
* 可变参数一般放在参数列表的末尾
*/
def add(ints: Int*):Int ={
var sum = 0;
for(v <- ints)
sum = sum + v
sum
}
def makePerson(parames: Any*): Unit = {
}
//传递默认值
def sub(a: Int = 6, b: Int = 6) = {
a - b
}
def main(args: Array[String]): Unit = {
println(add(6))
println(add(1,2))
println(add(1,2,3,4,5))
println(sub()) //使用默认值
println(sub(7,8))
println(sub(b = 9))
}
}
高阶函数 和 部分参数应用函数
package day02
object HighFunction extends App{ //这样可以不写main函数了,不知道为啥
/**
* 高阶函数: 将其他函数作为参数 或者 其结果为函数的函数
* def apply(f: Int => String, v: Int) = f(v) 该方法参数是一个整型参数返回值为整型的函数f 和 一个整型参数v,返回值为一个函数
* def layout(x: Int) = "[" + x.toString() + "]"
*
* //调用: println(apply(layout,10))
*
* 部分参数应用函数
* 如果函数传递所有预期的参数,则表示已完全应用它,如果只传递几个参数并不是全部参数,那么将返回部分应用的函数。
* 这样就可以方便德绑定一些参数,其余的参数可稍后填写补上
* 交互式窗口中示例:
* def m(a: Int, b: Int) = a + b
* -> m:(a: Int ,b: Int)Int
* m(1,_:Int)
* ->res7: Int =>Int = <function1>
* val partM = m(1,_:Int)
* ->partM: Int => Int = <function1>
* partM(13)
* ->res8: Int = 14
* */
}
package day02
import java.util.Date
object PartParamFunc extends App{
def log(date: Date, message: String ) ={
println(s"$date,$message")
}
val date = new Date()
//调用log的时候,传递了一个具体的时间参数,message 为待定参数
//logBoundDate 成了一个新的函数,只有log 的部分参数
val logBoundDate:(String) =>Unit = log(date,_: String)
//调用logBoundDate的时候,只需要传递待传的message参数即可
logBoundDate("fuck jerry")
logBoundDate("hello")
log(date,"taoato")
}
柯里化(Currying)
package day02
object CurryingFunc extends App {
/**
* 柯里化函数:柯里化(Currying)指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程,
* 新的函数返回一个以原有第二个参数为参数的函数。
*/
// def add(x: Int,y: Int) = x + y
// //我们应用的时候应该是这样调用: add(1,2)
// //我们将上面的函数变一下形
// def add(x: Int)(y: Int) = x + y
// //那么我们应用的时候,应该是这样的,add(1)(2) 最后返回结果都是一样的,这种方式(过程)就叫柯里化。
// // 经过柯里化之后,函数的通用性有所降低,但是适用性有所提高。
/**
* 分析下面其演变过程
* def add(x: Int) = (y: Int) => x + y
* (y: Int)=> x + y 为一个匿名函数,也就是意味着add 方法的返回值为一个匿名函数
* val x = add(3)
* x(5) ==8
*/
}
shift + shift 可以检索函数,方法等
偏函数
package day02
object PartialFunction {
/**
* 偏函数
* 被包在花括号内没有match的一组case语句是一个偏函数,他是PartialFunction[A,B]的一个实例,
* A代表参数类型,B代表返回类型,常用作输入模式匹配
*/
def func1: PartialFunction[String, Int] ={ //必须使用case
case "one" => 1
case "two" => 2
case _ => -1 //_任意情况
}
//match case
def func2(num: String): Int = num match{
case "one" => 1
case "two" => 2
case _ => -1
}
def func3(str: String): Int ={
if(str.equals("a"))
97
else
0
}
def f1: PartialFunction[Any,Int] ={
case i: Int => i * 10
}
def main(args: Array[String]): Unit = {
println(func3("a"))
println(func2("one"))
println(func1("one"))
val arr = Array[Any](1, 2, 3, 4, "你大爷的")//这样传进去不会出错,不符合的类型不会处理
val arr1 = Array(1, 2, 3, 4)
val collect = arr.collect(f1)
println(collect.toBuffer)
arr1.map((x: Int) => x * 10) //使用map时候不能把什么类型都往里逮,使用偏函数可以
// arr1.map(x =>x * 10) //系统自动推测x 类型
// arr1.map(_ * 10)
/**
* 还可以这样写:
* arr1.map(x => x * 10)
* arr1.map(_ * 10)
* arr1.map{case x: Int => x * 10}感觉map好像也有了偏函数功能,其实大括弧case 编译器这里会自己把它转换为偏函数
* 所以前面的arr还可以这样实现乘十的功能。
* arr.map{case x: Int => x * 10}
*
*/
}
}