作用域省略
scala中,如果方法只有一个参数,可以省略.作用域符号,给出一个说明:
package example
class Person(var age: Int) {
def setAge(n: Int) = age = n
}
object MyExample {
def main(args: Array[String]): Unit = {
val p = new Person(0)
p setAge 10 // 这里省略.和()
println(p.age)
}
}
高阶函数
scala中,函数是“一等公民”,即函数可以类似变量那样,可以赋值、作为其他函数or方法的输入、作为返回值。当一个函数作为上述的作用时,我们称之为高阶函数。举个例子:
package example
object MyExample {
def main(args: Array[String]): Unit = {
val salaries = Seq(1000, 2000, 3000)
val times2 = (x: Int) => x * 2 // 作为变量赋值
val newSalaries = salaries.map(times2) // 作为函数参数
println(newSalaries.toString())
val newSalaries1 = newSalaries.map(x => x * 2) // 使用匿名函数
println(newSalaries1.toString())
val newSalaries2 = newSalaries1.map(_ * 2) // 简写
println(newSalaries2.toString())
}
}
代码输出:
List(2000, 4000, 6000)
List(4000, 8000, 12000)
List(8000, 16000, 24000)
我们也可以强制转换方法为函数,举个例子:
package example
case class TemperatureConverter(temperatures: Seq[Double]) {
def convertCtoF(temp: Double): Double = temp * 2 + 38
// 这里map的函数直接使用方法,并转换成函数
def convertTempList: Seq[Double] = temperatures.map(convertCtoF)
}
object MyExample {
def main(args: Array[String]): Unit = {
val tc = TemperatureConverter(Seq(20.0, 18.7, 13.2, 14.3))
val temps = tc.convertTempList
println(temps.toString)
}
}
代码输出:
List(78.0, 75.4, 64.4, 66.6)
我们也可以在一个类中,把其他类的方法z我们也可以在一个类中,把其他类的方法转换成函数,举个例子:
package example
class Foo {
def add2(n: Int): Int = n + 2
}
object Foo {
def add3(n: Int): Int = n + 3
}
object MyExample {
def main(args: Array[String]): Unit = {
val s = Seq(1, 2, 3, 4)
val foo = new Foo
val s1 = s.map(foo.add2) // 需要使用实例化后的对象
println(s1.toString)
val s2 = s.map(Foo.add3) // object中的方法可以直接引用
println(s2.toString)
}
}
代码输出:
List(3, 4, 5, 6)
List(4, 5, 6, 7)
函数也可以作为其他函数或者方法的参数,举个例子:
package example
class Num2(a: Int, b: Int) {
// op是一个方法
def numOp(op: (Int, Int) => Int): Int = {
val x = a + 10
val y = b * 2
op(a, b)
}
}
object MyExample {
def main(args: Array[String]): Unit = {
val num2 = new Num2(10, 2)
val op = (a: Int, b: Int) => a + b // 定义方法
val res = num2.numOp(op)
println(res)
}
}
函数也可以作为返回值,举个例子:
package example
object MathFactory {
def numOp(n: Int): (Int) => Int = {
if (n > 0) {
(a: Int) => a * 2
} else {
(b: Int) => b * 3
}
}
}
object MyExample {
def main(args: Array[String]): Unit = {
val n = 3
val op1 = MathFactory.numOp(1)
val res1 = op1(n)
println(res1)
val op2 = MathFactory.numOp(-1)
val res2 = op2(n)
println(res2)
}
}
代码输出:
6
9
函数内部也可以有嵌套方法,比如:
package example
object MyExample {
def main(args: Array[String]): Unit = {
def add2(n: Int): Int = n + 2 // main方法内部继续嵌套main方法
println(add2(3))
}
}
函数柯理化
直接上代码:
package example
object MyExample {
def normalize(base: Int)(a: Int, b: Int, c: Int): Int = {
println(s"base=$base")
(a + b + c) / base
}
def main(args: Array[String]): Unit = {
// 函数柯理化,注意这里的下划线表示省略参数
def carry2 = normalize(2)_
val res = carry2(1, 2, 3)
println(res)
}
}
代码输出:
base=2
3