函数"/>
Scala 异常、模式匹配、隐式转换、caseclass、偏函数
Scala 中的异常处理:
- 在 scala 中只有一个 catch
- 在 catch 中有多个 case, 每个 case 可以匹配一种异常 case ex: ArithmeticException
- => 关键符号,表示后面是对该异常的处理代码块
- finally 最终要执行的
Scala 异常处理小结
-
我们将可疑代码封装在 try 块中。 在 try 块之后使用了一个 catch 处理程序来捕获异常。如果发生任何异常,catch 处理程序将处理它,程序将不会异常终止。
-
Scala 的异常的工作机制和 Java 一样,但是 Scala 没有“checked(编译期)”异常,即 Scala 没有编译异常这个概念,异常都是在运行的时候捕获处理。
-
用 throw 关键字,抛出一个异常对象。所有异常都是 Throwable 的子类型。throw 表达式是有类型的,就是 Nothing,因为 Nothing 是所有类型的子类型,所以 throw 表达式可以用在需要类型的地方
def test(): Nothing = {
throw new ArithmeticException(“算术异常”)//Exception(“异常 NO1 出现~”) } -
在 Scala 里,借用了模式匹配的思想来做异常的匹配,因此,在 catch 的代码里,是一系列 case 子句来匹配异常。当匹配上后 => 有多条语句可以换行写,类似 java 的 switch case x: 代码块…
-
异常捕捉的机制与其他语言中一样,如果有异常发生,catch 子句是按次序捕捉的。因此,在 catch 子句中,越具体的异常越要靠前,越普遍的异常越靠后,如果把越普遍的异常写在前,把具体的异常写在后,在 scala 中也不会报错,但这样是非常不好的编程风格。
-
finally 子句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用于对象的清理工作,这点和 Java 一样。
-
Scala 提供了 throws 关键字来声明异常。可以使用方法定义声明异常。 它向调用者函数提供了此方法可能引发此异常的信息。 它有助于调用函数处理并将该代码包含在 try-catch 块中,以避免程序异常终止。
隐式转换:
-
隐式转换函数的函数名可以是任意的,隐式转换与函数名称无关,只与函数签名(函数参数类型和返回值类型)有关。
-
隐式函数可以有多个(即:隐式函数列表),但是需要保证在当前环境下,只有一个隐式函数能被
//隐式函数应当在作用域才能生效
implicit def f1(d:Double): Int = { //底层 生成 f1$1 d.toInt
}
模式匹配:
- match (类似 java switch) 和 case 是关键字
- 如果匹配成功, 则 执行 => 后面的代码块.
- 匹配的顺序是从上到下,匹配到一个就执行对应的 代码
- => 后面的代码块 不要写 break ,会自动的退出 match
- 如果一个都没有匹配到,则执行 case _ 后面的代码块
match 的细节和注意事项
- 如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句
- 如果所有 case 都不匹配,又没有写 case _ 分支,那么会抛出 MatchError
- 每个 case 中,不用 break 语句,自动中断 case
- 可以在 match 中使用其它类型,而不仅仅是字符
- => 等价于 java swtich 的 :
- => 后面的代码块到下一个 case, 是作为一个整体执行,可以使用{} 扩起来,也可以不扩。
case class
- 样例类仍然是类
- 样例类用 case 关键字进行声明。
- 样例类是为模式匹配而优化的类
- 构造器中的每一个参数都成为 val——除非它被显式地声明为 var(不建议这样做)
- 在样例类对应的伴生对象中提供 apply 方法让你不用 new 关键字就能构造出相应的对象
- 提供 unapply 方法让模式匹配可以工作
- 将自动生成 toString、equals、hashCode 和 copy 方法(有点类似模板类,直接给生成,供程序员使用)
- 除上述外,样例类和其他类完全一样。你可以添加方法和字段,扩展它们
偏函数小结
- 使用构建特质的实现类(使用的方式是 PartialFunction 的匿名子类)
- PartialFunction 是个特质(看源码)
- 构建偏函数时,参数形式 [Any, Int]是泛型,第一个表示参数类型,第二个表示返回参数
- 当使用偏函数时,会遍历集合的所有元素,编译器执行流程时先执行 isDefinedAt()如果为 true , 就会执行 apply, 构建一个新的 Int 对象返回
- 执行 isDefinedAt() 为 false 就过滤掉这个元素,即不构建新的 Int 对象.
- map 函数不支持偏函数,因为 map 底层的机制就是所有循环遍历,无法过滤处理原来集合的元素
- collect 函数支持偏函数
object PartialFun03 { def main(args: Array[String]): Unit = { //可以将偏函数简写 def partialFun2: PartialFunction[Any,Int] = { //简写成 case 语句 case i:Int => i + 1 case j:Double => (j * 2).toInt } val list = List(1, 2, 3, 4, 1.2, 2.4, 1.9f, "hello") val list2 = list.collect(partialFun2) println("list2=" + list2) //第二种简写形式 val list3 = list.collect{ case i:Int => i + 1 case j:Double => (j * 2).toInt case k:Float => (k * 3).toInt } println("list3=" + list3) // (2,3,4,5) }
}
柯里化
- 函数编程中,接受多个参数的函数都可以转化为接受单个参数的函数,这个转化过程就叫柯里化
- 柯里化就是证明了函数只需要一个参数而已。其实我们刚才的学习过程中,已经涉及到了柯里化操作。
- 不用设立柯里化存在的意义这样的命题。柯里化就是以函数为主体这种思想发展的必然产生的结果。(即:柯里化是面向函数思想的必然产生结果)
更多推荐
Scala 异常、模式匹配、隐式转换、caseclass、偏函数
发布评论