Scala函数

Scala是一门函数式语言,函数在Scala里属于First-Class Value,意味着在Scala中函数可以像其它值一样用作参数或者返回值,也可以赋值给变量或存储在某些存储结构中。Scala对于函数有很多特性能能够使代码更加简洁,复用性更高。

函数定义

def functionName(paramName : paramType) : returnType = {
        //TODO  function body
}
scala> def sum(a : Int, b : Int) : Int = {
     | a + b
     | }
sum: (a: Int, b: Int)Int

scala> sum(1,2)
res0: Int = 3
在REPL中定义了一个函数sum,函数接收两个参数a和b,类型均为Int,返回类型也为Int,函数返回两个参数的和。如果函数体只有一个语句大括号是可以省略的。另外基于Scala强大的类型推导机制,函数的返回类型往往也可以省略。

scala> def sum(a : Int, b : Int) = a + b
sum: (a: Int, b: Int)Int

scala> sum(1,2)
res1: Int = 3

高阶函数

在Scala中,高阶函数表示使用其它函数作为参数或者作为返回值的函数。在介绍高阶函数之前先介绍“函数类型”和“匿名函数”两个概念。
函数类型 : A => B表示该函数接收类型为A的参数并返回类型为B的返回结果。A可以是参数类型列表。如下highOrderFunc的参数为一个函数f,函数f的类型为(Int, Int) => Int
scala> def sum(a : Int, b : Int) = a + b
sum: (a: Int, b: Int)Int

scala> def highOrderFunc(f : (Int, Int) => Int) : Int = f(1,2)
highOrderFunc: (f: (Int, Int) => Int)Int

scala> highOrderFunc(sum)
res4: Int = 3

匿名函数:匿名函数的定义为:(参数列表) => {函数体}。在REPL中定义了一个匿名函数,自动生成的变量名为res2,可以通过res2来调用刚刚定义的匿名函数。

scala> (a : Int, b : Int) => a + b
res2: (Int, Int) => Int = <function2>

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

scala> def highOrderFunc2() = (x: Int, y: Int) => x * x + y * y
highOrderFunc2: ()(Int, Int) => Int

scala> val func2 = highOrderFunc2()
func2: (Int, Int) => Int = <function2>

scala> func2(2,3)
res2: Int = 13

函数参数求值方式

在Scala语言中,函数实参的求值方式有call by value和call by name两种方式,参数定义方式分别为
  • Call By Value: x: Int
  • Call By Name: x: => Int
scala> def func1(x: Int, y: Int) = x + y
func1: (x: Int, y: Int)Int

scala> def fund2(x: Int, y: => Int) = x + y
fund2: (x: Int, y: => Int)Int

func1有两个Int类型的参数,其求职策略均为Call By Value。func2也有两个参数其中参数x的求值策略为Call By Value,y的求值策略为Call By Name。
  • Call By Value: 对函数实参的求值只做一次,在函数中的多次使用值均相同
  • Call By Name:参数在函数中每次使用均会求值
scala> var count = 0
count: Int = 0

scala> def addOne: Int = {
     | count += 1
     | count
     | }
addOne: Int

scala> def func1(x: Int) = {
     | println("count=" + x)
     | println("count=" + x)
     | }
func1: (x: Int)Unit

scala> def func2(x: => Int) = {
     | println("count=" + x)
     | println("count=" + x)
     | }
func2: (x: => Int)Unit

scala> func1(addOne)
count=1
count=1

scala> func2(addOne)
count=2
count=3

在REPL中先定义了一个变量count值为0,定义了一个addOne函数,在函数中对count加1并返回count的当前值。函数func1和func2均两次打印传入的参数x。func1的求值方式为Call By Value,func2的求值方式为Call By Name。第一次调用func1(addOne),会首先调用addOne对count加1并返回1,此时x的值就为1,两次打印的结果也为1.调用func2并不会首先执行addOne求出x的值,而是用addOne替换x,两次打印实际上变为println(“count=“ + addOne)  println(“count=“ + addOne)。因此addOne会被执行两次。最终打印出的结果为2和3.这就是call by value和call by name的区别。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值