Scala中函数和方法的不同

1.定义方式不同

1.1方法 用def

def methodName1 (p1:Int, p2:Int) : Int = {

val c = a+b

return c

}

1.2函数  用var

var funcName1 = (p1:Int, p2:Int) => p1 +p2

 

2.方法名是 ‘’调用‘’ 方法本身的,

函数名 ‘’代表‘’ 函数本身

 

3.参数列表() 可不可省略

3.1方法的参数列表可以省略

def methodName2 :Int={
  var c = 3
  print("this is 3")
return c
}

 

3.2函数参数列表 不能省略

var funcName2 = ()  => print("test")

即是 没有参数也要写上 括号

 

4.可不可以指定返回值类型

方法可以指定

函数不能指定

 

详细:

Scala 中的方法跟 Java 的方法一样,方法是组成类的一部分。方法有名字、类型签名,有时方法上还有注解,以及方法的功能实现代码(字节码)。

Scala 中的函数是一个完整的对象。Scala 中用 22 个特质(trait)抽象出了函数的概念。这 22 特质从 Function1 到 Function22:

如上图中的 Function10 代表的是:有 10 个形参,返回值为 R(协变)的函数。

Scala 中的函数其实就是继承了这些 Trait 的类的对象,如:我们通过函数字面量定义一个函数

其实上述函数的定义方式跟如下定义方式等同:

由于 Function2 是特质,不能直接 new。上述 new Function2[Int,Int,Int](){} 其实是定义并实例化一个实现了 Function2 特质的类的对象。

apply 是 scala 中的语法糖:对一个对象 obj 上调用 obj(),scala 编译器会转换为 obj.apply();在一个类 clazz 上调用 clazz(),scala 编译器会转换为 clazz_company_obj.apply(),其中 clazz_company_obj 为 clazz 的伴生对象。

 

具体的差异,总结为如下几点:

1.方法不能作为单独的表达式而存在(参数为空的方法除外),而函数可以。如:

在如上的例子中,我们首先定义了一个方法 m,接着有定义了一个函数f。接着我们把函数名(函数值)当作最终表达式来用,由于f本身就是

一个对象(实现了 FunctionN 特质的对象),所以这种使用方式是完全正确的。但是我们把方法名当成最终表达式来使用的话,就会出错。

2.函数必须要有参数列表,而方法可以没有参数列表

在如上的例子中,m1方法接受零个参数,所以可以省略参数列表。而函数不能省略参数列表

3.方法名是方法调用,而函数名只是代表函数对象本身

这个比较容易理解。因为保存函数字面量的变量(又称为函数名或者函数值)本身就是实现了 FunctionN 特质的类的对象,要调用对象的 apply方法,就需要使用obj()的语法。所以函数名后面加括号才是调用函数。如下:

4.在需要函数的地方,如果传递一个方法,会自动进行ETA展开(把方法转换为函数)

如果我们直接把一个方法赋值给变量会报错。如果我们指定变量的类型就是函数,那么就可以通过编译,如下:

当然我们也可以强制把一个方法转换给函数,这就用到了 scala 中的部分应用函数:

5.传名参数本质上是个方法

传名参数实质上是一个参数列表为空的方法,如下:

如上代码实际上定义了一个方法 m1,m1 的参数是个传名参数(方法)。由于对于参数为空的方法来说,方法名就是方法调用 ,所以List(x,x)实际上是进行了两次方法调用。

由于 List(x,x) 是进行了两次方法调用,所以得到两个不同的值。

如果我们稍微修改一下函数的m1的定义,把x先缓存起来,结果就会跟以前大不一样。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值