- Scala中方法和函数几乎是可以等同的, 只是函数的使用方式更加灵活多样
- 函数式编程是从编程方式的角度来谈的, Scala中,函数可以像变量一样, 既可以作为函数的参数使用,也可以将函数赋值给一个变量, 函数的创建不用依赖于类或对象
函数定义
- 基本语法
def 函数名(参数名:参数类型,...):返回值类型 = {
函数体
}
def: 函数声明关键字
返回值:
- : 返回值类型 =,返回该类型返回值
- 只有一个等于, 表示返回值不确定,使用类型推导完成
- 什么都没有, return不生效
- 如果没有写return语句, 默认最后一行的执行结果作为返回值
def test(): String ={
return "示例函数"
}
注:
函数的形参列表可以是多个.如果函数没有形参, 调用时可以不写()
因为Scala可以自行推断, 所以在省略return关键字的场合, 返回值类型也可以省略
如果函数明确使用return关键字,那么函数返回就不能使用自动推断了, 要明确写出, 如果返回值地方什么都不写,那么返回值为()即Unit
如果函数明确声明无返回值即使用Unit,那么及时使用return关键字也没有返回值
如果明确函数无返回值,或者返回值类型不确定,那么返回值类型可以省略(或声明为Any)
Scala在任意地方都可以定义函数,比如可以在一个函数中声明一个函数, 但是这两个函数在改类中的使用范围是相同的,其他函数也可以调用函数中声明的函数, Scala底层是将该函数定义为一个private final类型的方法
甚至可以这么声明函数:
Scala底层中,将这些所有函数名,参数相同的函数,以函数名+
$
+数字进行区分,即上面在Scala的.class文件中是以,sayOk()
、sayOk$1()
、sayOk$2()
存在的
- Scala函数的形参,在声明参数时,会直接赋初始值,在调用时如果没有指定形参,会使用默认值
- 如果函数存在多个参数, 每一个参数都可以设定默认值, 那么这个时候,传递的参数到的是复制给没有默认值的参数,还是覆盖就不确定了,这种情况下可以使用带名参数
//一.如果此时使用的是不带名的参数,那么除了带有默认值之外的其他参数必须要填写,且有默认值的参数必须在后面 def mysqlConn(address:String,port:String,username:String="root",password:String="123456"): Unit ={ println(address) println(port) println(username) println(password) } mysqlConn("127.0.0.1","3306") //二.如果带默认值的参数写在了不带默认值的参数之前,那么调用的时候,有两种方法 def mysqlConn(address:String="127.0.0.1",port:String): Unit ={ println(address) println(port) } //1,填写所有参数 mysqlConn("127.0.0.1","3306") //2,指定参数名 mysqlConn(port="127.0.0.1") //三.如果所有的参数均有默认值,在不指定参数名的情况下,默认从左到右进行赋值 def mysqlConn(address:String="127.0.0.1",port:String:"3306"): Unit ={ println(address) println(port) } //默认赋值给address mysqlConn("3306") //赋值给port mysqlConn(port="3306")
- 形参默认是val的,因此不能再函数中进行修改
- 递归函数未执行之前是无法推断出结果类型的, 因此在使用时必须有明确的返回值类型
- Scala的可变参数:
//*表示可变参数,只能放在最后一个,args是一个集合 def sum(n1:Int,n2:Int,args:Int*):Int{}
过程
将函数返回值类型为Unit的函数称之为过程, 如果明确函数没有返回值,那么等号可以省略;
如果函数声明时没有返回值类型,但是有等号,可以进行类型推断,此时该函数是有返回值的,该函数并不是过程
惰性函数和异常
惰性函数
- 当函数返回值被声明为lazy时, 函数的执行将被推迟,直到对此首次取值时,该函数才会执行,这种函数就是惰性函数,即java中的懒加载
lazy val res=fbnq(12)//只有当使用res时才会执行函数
- lazy不能修饰var变量
- 不仅仅是在调用函数时,加了lazy会导致函数执行被推迟,在声明变量时,添加lazy的变量的值分配也会推迟
lazy val const="123456"//赋值123456将会被推迟
异常
Scala提供try-catch处理异常
try{
}catch {//catch只有一个,每个case可以匹配一个异常,=>后处理异常,可以是代码块
case ex:ArithmeticException=>print("ArithmeticException")
case ex:Exception=>print("Exception"+ex.getCause)
}finally {
print("...")
}
Scala没有编译异常, 异常都是在运行的时候捕获处理的
用throw抛出一个异常,所有的异常都是Throwable的子类型, throw表达式是有类型的,就是Nothing
如果有异常发生,catch是按顺序捕捉的,因此建议在catch子句中,越详细的异常越靠前写,越广的异常越靠后写
通过throws注解来声明异常
@throws(classOf[NotImplementedError]) def mysqlConn(address:String="127.0.0.1",port:String): Unit ={}