从JAVA到scala(一):函数也是变量

准确地说,函数也是对象,scala中一切变量都是对象,包括函数,没有例外,之所以要说函数也是变量,是因为scala的函数声明就像普通变量的声明一样——“def”(或者val) + “=”(这两个符号必不可少),格式如下:

def 函数变量名[(参数列表)]:[返回值] = 函数体

1. 通用函数声明

这是最常见的方式,也是最完整的写法,我们以简单的加法为例,如下:

def add(a: Int, b: Int): Int = {
    return a + b
}

既然是最完整的写法,必然有可以省略的地方,依赖于scala强大的类型推到,返回值类型,return都可以省略,最后可以简写为如下的形式:

def add(a: Int, b: Int) = a + b

猛地一看,还以为是add就是一个普通的变量,尤其是没有参数的函数,如下:

#   请注意,括号必不可少
def add() = 10

尤其是它的调用方式,更加让人迷惑,括号也是可以省略的,如下:

//  输出10
println(add)

2. 匿名函数声明

匿名函数跟JAVA8的lambda表达式与函数接口非常相似,但因为没有接口声明,所以必须提供参数类型,如下:

def add = (a: Int, b: Int) => a + b

如果跨越多行,只需要加上花括号就可以了,如下:

def add = (a: Int, b: Int) => {
  a + b
}

匿名函数还有一个重要的特性,就是无法定义返回值类型,所以返回类型完全靠类型推导。

3. 函数作为返回值

scala作为一种函数式编程语言,那么函数作为返回值就是很平凡的事情了,其函数签名的返回值必须是函数形式,这也是“=>”的用武之地了,继续以加法为例,如下:

//  请对比通用函数声明
def add(a: Int, b: Int): () => Int = {
  val r = a + b
  //    返回函数
  () => r
}

在上面的例子中,“() => Int”整个作为函数的返回值声明,如果简化为匿名函数形式,代码如下:

//  省略了返回类型
def add = (a: Int, b: Int) =>  {
  val r = a + b
  () => r
}

4. 函数作为参数

函数作为参数,声明时必须要省略变量名称,如下:

//   直接将fn: (Int, Int) => Int作为一个参数
def oper(a: Int, b: Int, fn: (Int, Int) => Int) = {
  fn(a, b)
}
//  现在可传入函数了
println(oper(20, 30, add))

在上面的例子中,“fn: (Int, Int) => Int”整个作为一个参数,表示接受一个有两个整数参数并返回一个整数值的函数。

5. def、val、var的区别

除了不可以定义类方法、对象方法以及特征方法外,val、var与def一样,都可以用来声明方法,有文章说val的效率更高,并且只保存一个Function1实例,而def则效率略差,但从我的测试效果来看,并不存在这样的现象(scala版本2.12.3),无论是val、var、def都是返回同一个实例(对象地址完全一样),更让人混乱的是,def还可以用于定义变量,效果跟val一模一样(不可变更)。简单总结下(如果有人发现不对,请一定告诉我):
1. 在函数内定义变量时,def与val一模一样,都是不可变更的;
2. val、var、def都可以定义函数,都可以定义类、对象、特征属性;
3. 只有def才可以定义类方法、对象方法以及特征方法;
4. 只有val、var才能用于构造函数的参数声明;

class Fires(var x:Int, var y:Int) {
  //  def定义属性
  def PI:Int = 100

  def add(a: Int, b:Int): Int = {
    //  val定义方法
    val fn = (x: Int, y: Int) => x + y
    fn(a, b)
  }
}

结论

函数跟普通的变量一模一样,都是一个对象,并且划分为函数声明与函数赋值两部分,所以很好记忆,函数一定有“def”声明与“=”赋值两部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值