03_Scala 函数_过程_异常
函数 为完成某一功能的程序指令(语句)的集合
在scala中,方法和函数几乎等同(比如定义、使用、运行机制都一样的)
支持的函数的多种使用方式。如:像变量一样,既可以作为函数的参数使用,也可以将函数赋值给一个变量.
函数的创建不用依赖于类或者对象,(Java当中,函数的创建则要依赖于类、抽象类或者接口)
基本语法
def 函数名 ([参数名: 参数类型], ...)[[: 返回值类型] =] {
语句...
return 返回值
}
函数声明关键字为def (definition)
[参数名: 参数类型], ...:表示参数列表, 可以没有。 如有,多个参数使用逗号间隔
函数中语句:表示为了实现某一功能代码块
函数可以有/没有返回值,如无return,默认最后一行结果为返回值
返回值形式1: : 返回值类型 =
返回值形式2: = 表示返回值类型不确定,使用类型推断完成
返回值形式3: 表示没有返回值(return 不生效)
object FundemoTest1 {
def main(args: Array[String]): Unit = {
val n1 = 10; val n2 = 20
println("res=" + getRes(1, 2, ')'))
val res = sum(n1, n2)
println("res=" + res)
}
def sum(n1: Int, n2: Int): Int = {
return n1 + n2
}
//定义函数/方法
def getRes(n1: Int, n2: Int, oper: Char) = {
if (oper == '+') {
n1 + n2 //返回
} else if (oper == '-') {
n1 - n2
} else {
//返回null
null
}
}
函数-调用机制 不同的栈,指针上下移动,先进后出
函数-递归调用 函数在函数体内又调用了本身
递归重要原则:
1 程序执行一个函数时,就创建一个新的受保护的独立空间(新函数栈)
2 函数的局部变量是独立的,不会相互影响
3 递归必须向退出递归的条件逼近,否则就是无限递归,有个判断(if)
4 当一个函数执行完毕,或者遇到return,就会返回,遵守谁调用,就将结果返回给谁
函数Details
1 函数的形参列表可以是多个, 如果函数没有形参,调用时 可以不带()
2 形参列表和返回值列表的数据类型可以是值类型和引用类型
3 函数可以根据函数体最后一行代码自行推断函数返回值类型,return关键字可以省略
4 Scala可以自行推断,在省略return关键字的场合,返回值类型也可以省略
5 如函数使用return关键字,函数返回就不能使用自行推断,明确写成 : 返回类型 = ,
如什么都不写,即使有return 返回值也为()
6 如函数明确声明无返回值(声明Unit),那么函数体中即使使用return关键字 也无返回值
7 如函数无返回值或不确定返回值类型,返回值类型可省略(类型推断)(或声明为Any)
8 函数中可以再声明/定义函数,类中可以再声明类 ,方法中可以再声明/定义方法 (final 私有不能改写+继承)
9 函数的形参,在声明时如直接赋初始值(默认值),调用时,如没指定实参,则会使用默认值。如指定了实参,则会覆盖默认值
10 如函数存在多个参数,每个参数都可设定默认值,传递的参数到底是覆盖默认值,还是赋值给没有默认值的参数,就无法确定
(默认按照声明顺序[从左到右])。在这种情况下,可以采用带名参数
11 函数的形参默认是val的,因此不能在函数中进行修改
12 递归函数未执行之前是无法推断出来结果类型,在使用时必须有明确的返回值类型
13 函数支持可变参数 (args :Int*) (可变参数需要写在形参列表的最后)
object FunDetailsTest1 {
def main(args: Array[String]): Unit = {
val d1 = new Dog
val d2 = dogTest1(100, d1)
println(d1.hashCode() == d2.hashCode()) //true
//10 多个参数,(默认按照声明顺序[从左到右])。在这种情况下,可以采用带名参数
mysqlCon(user = "alex", pwd = "123")
}
// 2 参列表和返回值列表的数据类型可以是值类型和引用类型 传入 dog 对象,返回dog 对象
def dogTest1(n1: Int, dd: Dog) :Dog ={
dd.name = "Robin"
dd
}
// 3 函数可以根据函数体最后一行代码自行推断函数返回值类型,return关键字可以省略
// 4 Scala可以自行推断,在省略return关键字的场合,返回值类型也可以省略
def getSum (n1: Int , n2: Int ) = {
n1 + n2
}
//5 如函数使用return关键字,函数返回就不能使用自行推断,明确写成 : 返回类型 = ,
// 如什么都不写,即使有return 返回值也为()
//如果写了return ,返回值类型就不能省略
def getSum2(n1: Int , n2: Int):Int ={
return n1 + n2
}
// 如果返回值这里什么什么都没有写,即表示该函数没有返回值 return无效
def getSum3(n1: Int , n2: Int) {
return n1 + n2
}
// 6 如函数明确声明无返回值(声明Unit),那么函数体中即使使用return关键字 也无返回值
//如果函数明确声明无返回值(声明Unit),那么函数体中即使使用return关键字也不会有返回值
def getSum4(n1: Int , n2: Int) : Unit ={
return n1 + n2
}
// 7 如函数无返回值或不确定返回值类型,返回值类型可省略(类型推断)(或声明为Any)
def getSum5 (n1: Int, n2:Int) ={ // : Any 也ok
if (n1 >0 && n2 > 10)
n1 + n2
else n1 - n2
}
def mysqlCon(add:String = "localhost",port : Int = 3306, user: String = "root", pwd : String = "root"): Unit = {
println("add=" + add)
println("port=" + port)
println("user=" + user)
println("pwd=" + pwd)
}
//12 递归函数未执行之前是无法推断出来结果类型,在使用时必须有明确的返回值类型
def f1(n:Int): Int = {
if (n==1) 1
else
f1(n-1)
}
//13 函数支持可变参数 (args :Int*) (可变参数需要写在形参列表的最后 )
def getSum6 (i: Int , args: Int*):Int ={
var sum = i
for (item <- args){
sum += i
}
sum
}
}
class Dog {
var name: String = "Bob"
}
过程
将函数的返回类型为Unit的函数称之为过程(procedure),如果明确函数没有返回值,那么等号可以省略
如函数声明时没有返回值类型,但是有 = 号,可以进行类型推断最后一行代码 这时函数实际是有返回值的,该函数并不是过程
开发工具的自动代码补全,会自动加上Unit,建议不加
def helloName(name: String):Unit = {
println("hello" + name)
// def a
// def b
// 一些列方法/函数 进行操作,但无返回值
}
惰性函数
当函数返回值/变量 被声明为lazy时,函数的执行将被推迟,直到我们调用,该函数/变量才会执行。
这种函数我们称之为惰性函数,在Java的某些框架代码中称之为懒加载 (单例模式懒汉式)
Details:
1 lazy 不能修饰 var 类型的变量
2 变量声明为lazy 时, 变量分配也会被推迟
object lazyTest1 {
def main(args: Array[String]): Unit = {
lazy val result = sum(10, 20) // lazy 修饰, 10,20 被赋值但sum并未调用
println("-----------------")
println("res=" + result) //在要使用result 前才调用sum 函数
}
//sum函数,返回和
def sum(n1: Int, n2: Int): Int = {
println("sum() 刚刚被执行了..") //说明刚刚被调用
return n1 + n2
}}
Scala异常
try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。
Java异常
1 java语言按照try—catch-catch...—finally的方式来处理异常; finally 都会执行( 通常在finally代码块中释放资源)
2 多个catch,把范围小的异常类写在前面,把范围大的异常类写在后面,否则编译错误。 "Exception 'java.lang.xxxxxx' has already been caught"类写在前面,把范围大的异常类写在后面,否则编译错误。 "Exception 'java.lang.xxxxxx' has already been caught"
Scala异常 details
1 将可疑代码封装在try块中, 使用一个catch处理程序来捕获异常
2 Scala没有“checked(编译期)”异常,异常都是在运行的时候捕获处理
3 用throw关键字,抛出一个异常对象。异常都是Throwable的子类型, throw表达式的类型是Nothing(Nothing是所有类型的子类型)
4 用模式匹配的思想来做异常的匹配,在catch的代码里,多个case子句来匹配异常,当匹配上后 => 有多条语句可以换行写
5 如果有异常发生,catch子句是按次序捕捉的,越具体的(小)异常越要靠前,越普遍的(大)异常越靠后
6 finally子句都会执行
7 Scala提供了throws关键字来声明异常 可以使用方法定义声明异常。
它向调用者函数提供了此方法可能引发此异常的信息。
它有助于调用函数处理并将该代码包含在try-catch块中,以避免程序异常终止。
在scala中,可以使用throws注释来声明异常
object exceptionTest {
def main(args: Array[String]): Unit = {
//1. 在scala中只有一个catch
//2. 在catch中有多个case, 每个case可以匹配一种异常 case ex: ArithmeticException
//3. => 关键符号,表示后面是对该异常的处理代码块
//4. finally 最终要执行的
try{
test()
}catch {
case ex: ArithmeticException => println("算术异常")
case ex: Exception => println("异常: " + ex.getMessage)
}finally {
println("关闭连接")
}
println("如果不被try catch 捕获,该句不会输出")
}
def test(): Nothing = {
throw new ArithmeticException("算术异常")//Exception("异常NO1出现~")
}
@throws(classOf[NumberFormatException]) //等同于Java NumberFormatException.class
def test1() ={
"abc".toInt
}
}
- 点赞
- 收藏
- 关注作者
评论(0)