scala中既有函数也有方法,在大多数情况下,不用理会其区别也可正常使用。但有时候还是要区分其异同。
Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
有些翻译上函数(function)与方法(method)是没有区别的。在写这篇博客的过程中,也参考了一些资料,但大都不能令我满意。所以,知道即可,不要过于追究这劳什子,scala是一门语言,语言自然以使用为第一要务。
方法
Scala中的方法跟Java的方法一样,方法是组成类的一部分。方法有名字、类型签名,有时方法上还有注解,以及方法的功能实现代码(字节码)
我们来定义看一个最经典的方法
函数
再来定义一个函数
其主要区别为:
在函数式编程语言中,函数是“头等公民”,它可以像任何其他数据类型一样被传递和操作
函数定义语法 用def来定义
可以定义传入的参数,要指定传入参数的类型
方法可以写返回值的类型也可以不写,会自动推断,有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候。
scala中函数有返回值时,可以写return,也可以不写return,会把函数中最后一行当做结果返回。当写return时,必须要写函数的返回值。
如果返回值可以一行搞定,可以将{}省略不写
传递给方法的参数可以在方法中使用,并且scala规定方法的传过来的参数为val的,不是var的。
如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。这种说法无论方法体里面什么逻辑都成立,scala可以把任意类型转换为Unit.假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。
函数也可作为参数传递到方法里
方法也可转为函数
方法及函数的调用
基本使用与java也类似。同样可以点出来,各种操作符也是可以使用的。
Scala中的+ - * / %等操作符的作用与Java一样,位操作符 & | ^ >> <<也一样。只是有一点特别的:这些操作符实际上是方法。
a + b
是如下方法调用的简写:
a.+(b)
a 方法 b可以写成 a.方法(b)
递归函数
注:递归函数的返回值是必须写的
/**
* 递归函数
* 5的阶乘
*/
def fun2(num :Int) :Int= {
if(num == 1)
num
else
num * fun2(num-1) //将函数也作为返回值,直到 num==1
}
print(fun2(5))
参数默认值及可变形参
scala与java类似,参数同样可以有默认值,且参数个数也可以是不定的
默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值。
如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称。
def fun3(a :Int = 10,b:Int) = {
println(a+b)
}
fun3(b=2)
对于参数不定的,参数之间要用逗号隔开
def fun4(elements :Int*)={
var sum = 0;
for(elem <- elements){
sum += elem
}
sum
}
println(fun4(1,2,3,4))
Trait
Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大。与接口不同的是,它还可以定义属性和方法的实现。
这里的trait字面意思是特质或者特征,这个词翻译成特征比较合适。它的意义和java,c#中接口很类似。但是trait支持部分实现,也就是说可以在scala的trait中可以实现部分方法。
一般情况下Scala的类可以继承多个Trait,从结果来看就是实现了多重继承。Trait(特征) 定义的方式与类类似,但它使用的关键字是 trait。
继承的多个trait中如果有同名的方法和属性,必须要在类中使用“override”重新定义。
trait中不可以传参数
trait Read {
val readType = "Read"
val gender = "m"
def read(name:String){
println(name+" is reading")
}
}
trait Listen {
val listenType = "Listen"
val gender = "m"
def listen(name:String){
println(name + " is listenning")
}
}
class Person() extends Read with Listen{
override val gender = "f"
}
object test {
def main(args: Array[String]): Unit = {
val person = new Person()
person.read("zhangsan")
person.listen("lisi")
println(person.listenType)
println(person.readType)
println(person.gender)
}
}
一下引用菜鸟教程的部分内容,原文摘录:
/* 文件名:Test.scala
* author:菜鸟教程
* url:www.runoob.com
*/
trait Equal {
def isEqual(x: Any): Boolean
def isNotEqual(x: Any): Boolean = !isEqual(x)
}
class Point(xc: Int, yc: Int) extends Equal {
var x: Int = xc
var y: Int = yc
def isEqual(obj: Any) =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
}
object Test {
def main(args: Array[String]) {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
println(p1.isNotEqual(p2))
println(p1.isNotEqual(p3))
println(p1.isNotEqual(2))
}
}
执行结果为:
false
true
true