定义函数最通用的方法是作为某个类或者对象的成员,这种函数被称为方法,其定义的基本语法为
def 方法名(参数列表):结果类型={方法体}
字面量包括整数字面量、浮点数字面量、布尔型字面量、字符字面量、字符串字面量、符号字面量、函数字面量和元组字面量
函数字面量可以体现函数式编程的核心理念
在函数式编程中,函数是“头等公民”,可以像任何其他数据类型一样被传递和操作,也就是说,函数
的使用方式和其他数据类型的使用方式完全一致了
这时,我们就可以像定义变量那样去定义一个函数,由此导致的结果是,函数也会和其他变量一样,开始有“值”
就像变量的“类型”和“值”是分开的两个概念一样,函数式编程中,函数的“类型”和“值”也成为两个分开的概念,函数的“值”,就是“函数字面量”
下面一点点引导大家更好地理解函数的“类型”和“值”的概念现在定义一个大家比较熟悉的传统类型的函数,定义的语法和我们之前介绍过的定义“类中的方法”类似(实际上,定义函数最常用的方法是作为某个对象的成员,这种函数被称为方法):
def counter(value: Int): Int = { value += 1}
上面函数的类型是:(int) => int
只有多个参数时(参数间间隔符是逗号)圆括号才是必须的,当参数只有一个时,括号可省略
int => int
上面就得到了函数的类型
现在来获取函数的值
事实上我们只需要把函数定义的类型声明去掉后得到的就是函数的值
(value) => {value += 1}
现在,我们再按照大家比较熟悉的定义变量的方式,采用Scala语法来定义一个函数。
声明一个变量时,我们采用的形式是:
val num:Int = 5
采用与上面类似的方式定义函数
val counter: Int => Int = { (value) => value += 1 }
从上面可以看出,在Scala
,函数已经是“头等公民”,单独剥离出来了“值”的概念,一个函数“值”就是函数字面量。这样,我们只要在某个需要声明函数的地方声明一个函数类型,在调用的时候传一个对应的函数字面量即可,和使用普通变量一模一样
我们不需要给每个函数都命名,因为我们可以使用匿名函数
(num:Int) => num*2
上面这种匿名函数的定义形式,我们经常称为Lambda
表达式。Lambda表达式
的形式如下:
(参数) => 表达式
//参数只有一个的时候,参数的圆括号可以省略
直接将匿名函数存放到变量中
val NumFunc = (num: Int) => num * 2
println(NumFunc(3))
当函数的每个参数在函数字面量内仅出现一次,可以省略“=>”并用下划线“_”作为参数的占位符来简化函数字面量的表示,第一个下划线代表第一个参数,第二个下划线代表第二个参数,依此类推
val add = (_:Int) + (_:Int)
println(add(4,5))
跳转顶部
高阶函数:当一个函数包含其它函数作为其参数或者返回结果为一个函数时,该函数被称为高阶函数
例:假设需要分别计算从一个整数到另一个整数的“连加和”、“平方和”以及“2的幂次和”
不使用告诫函数
def powerOfTwo(x: Int): Int = {
if (x == 0) 1 else 2 * powerOfTwo(x - 1)
}
def sumInts(a: Int, b: Int): Int = {
if (a > b) 0 else a + sumInts(a + 1, b)
}
def sumSquares(a: Int, b: Int): Int = {
if (a > b) 0 else a * a + sumSquares(a + 1, b)
}
def sumPowersOfTwo(a: Int, b: Int): Int = {
if (a > b) 0 else powerOfTwo(a) + sumPowersOfTwo(a + 1, b)
}
使用高阶函数
def sum(f: Int => Int, a: Int, b: Int):Int = {
if(a > b) 0 else f(a) + sum(f, a+1, b)
}
跳转顶部
遍历列表
Scala
遍历容器的标准写法
def foreach[U](f: Elem => U) :Unit
使用演示
val list = List(1,2,3)
val f = (i:Int) => println(i)
list.foreach(f)
也可以简写成以下两种方式
list foreach(i => println(i))
list foreach println
遍历Map
val map = Map("name" -> "Jack", "age" -> "21")
//详细写法
map foreach { kv => println(kv._1 + ":" + kv._2) }
//简写
map foreach { x => x match {
case (k, v) => println(k + ":" + v)
}
}
map foreach { case (k, v) => println(k + ":" + v) }
跳转顶部