Scala语言基础-函数

函数

1. 一般形式

1
2
3
def functionName(param: ParamType):ReturnType = {
//function body: expressions
}

在Scala中,需要为函数参数指定类型签名.

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
object func_test {
def hello(name: String): String = {
s"Hello,${name}"
} //> hello: (name: String)String

hello("Humbinal") //> res0: String = Hello,Humbinal

def hello2(name: String) = { 自动推断返回值类型
s"Hello,${name}"
} //> hello2: (name: String)String

def add(x:Int , y:Int) = x+y //> add: (x: Int, y: Int)Int //单个表达式的代码块可省略大括号

add(1,2) //> res1: Int = 3
}

如果函数不带参数,可以不写括号:

1
2
3
4
5
6
7
8
scala> def three() = 1 + 2
three: ()Int

scala> three()
res0: Int = 3

scala> three
res1: Int = 3

2. 匿名函数

scala可以创建匿名函数。

1
2
scala> (x: Int) => x + 1
res2: (Int) => Int = <function1>

这个函数为名为x的Int变量加1。

1
2
scala> res2(1)
res3: Int = 2

传递匿名函数,或将其保存成不变量。

1
2
3
4
5
scala> val addOne = (x: Int) => x + 1
addOne: (Int) => Int = <function1>

scala> addOne(1)
res4: Int = 2

如果函数有很多表达式,可以使用{}来格式化代码,使之易读。

1
2
3
4
scala> def timesTwo(i: Int): Int = {
println("hello world")
i * 2
}

对匿名函数也可以这样。

1
2
3
4
5
scala> { i: Int =>
println("hello world")
i * 2
}
res2: Int => Int = <function1>

在将一个匿名函数作为参数进行传递时,这个语法会经常被用到。

部分应用(Partial application)

你可以使用下划线“_”部分应用一个函数,结果将得到另一个函数。Scala使用下划线表示不同上下文中的不同事物,你通常可以把它看作是一个没有命名的神奇通配符。在{ _ + 2 }的上下文中,它代表一个匿名参数。你可以这样使用它:

1
2
3
4
5
6
7
scala> def adder(m: Int, n: Int) = m + n
adder: (m: Int,n: Int)Int
scala> val add2 = adder(2, _:Int)
add2: (Int) => Int = <function1>

scala> add2(3)
res50: Int = 5

也可以部分应用参数列表中的任意参数,而不仅仅是最后一个。

3. 柯里化函数

有时会有这样的需求:允许别人一会在你的函数上应用一些参数,然后又应用另外的一些参数。

例如一个乘法函数,在一个场景需要选择乘数,而另一个场景需要选择被乘数。

1
2
scala> def multiply(m: Int)(n: Int): Int = m * n
multiply: (m: Int)(n: Int)Int

你可以直接传入两个参数。

1
2
scala> multiply(2)(3)
res0: Int = 6

你可以填上第一个参数并且部分应用第二个参数。

1
2
3
4
5
scala> val timesTwo = multiply(2) _
timesTwo: (Int) => Int = <function1>

scala> timesTwo(3)
res1: Int = 6

你可以对任何多参数函数执行柯里化。例如之前的adder函数

1
2
scala> (adder _).curried
res1: (Int) => (Int) => Int = <function1>

可变长度参数
这是一个特殊的语法,可以向方法传入任意多个同类型的参数。例如要在多个字符串上执行String的capitalize函数,可以这样写:

1
2
3
4
5
6
7
8
def capitalizeAll(args: String*) = {
args.map { arg =>
arg.capitalize
}
}

scala> capitalizeAll("rarity", "applejack")
res2: Seq[String] = ArrayBuffer(Rarity, Applejack)

0%