作者:jiangzz
电话:15652034180
微信:jiangzz_wx
微信公众账号:jiangzz_wy
百知教育
异常处理
Scala 的异常处理和其它语言比如 Java 类似。Scala 的方法可以通过抛出异常的方法的方式来终止相关代码的运行,不必通过返回值。Scala 抛出异常的方法和 Java一样,使用 throw 方法,例如,抛出一个新的参数异常:
throw new IllegalArgumentException
如果有异常发生,catch字句是按次序捕捉的。因此,在catch字句中,越具体的异常越要靠前,越普遍的异常越靠后。 如果抛出的异常不在catch字句中,该异常则无法处理,会被升级到调用者处。捕捉异常的catch子句,语法与其他语言中不太一样。在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case字句,如下例所示:
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
object Test {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException =>{
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
}
}
}
finally 语句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,实例如下:
import java.io.FileReader
import java.io.FileNotFoundException
import java.io.IOException
object Test {
def main(args: Array[String]) {
try {
val f = new FileReader("input.txt")
} catch {
case ex: FileNotFoundException => {
println("Missing file exception")
}
case ex: IOException => {
println("IO Exception")
}
} finally {
println("Exiting finally...")
}
}
}
隐式传值\隐式转换
隐式值获取
分别使用implicit
关键字和implicitly
关键字声明隐式值和隐式注入等操作。
scala> implicit val n=1
scala> val b=implicitly[Int]
b: Int = 1
使用implicitly[类型],必须保证当前上下文有且仅有一个隐式值类型,一般这种隐式值变量的声明写在object单例类或者伴生对象中。
隐式注入值
implicit val s="您好"
def sayHi1(implicit msg:String):Unit={
println(msg)
}
def sayHi2(name:String)(implicit msg:String):Unit={
println(msg+" "+name)
}
sayHi1
sayHi2("张三")
sayHi2("李四")("早上好")
要求隐式注入的值一般都会写成柯理化形式并且保证需要隐式注入的值写在最后。
隐式参数转换
该方式是通过隐式转换将参数不满足的类型转为所需类型,Scala在编译代码的时候,先尝试正常编译如果发现编译类型不匹配,会尝试加载当前上下文中是否存在该类型和目标类型的一种隐式转换(这种转换必须唯一),如果存在则编译通过。
def main(args: Array[String]): Unit = {
implicit def str2stu(v:String):Student={
new Student(v)
}
sayHi2Stu("王五")
}
def sayHi2Stu(stu:Student):Unit={
println("学生:"+stu.name+" 你好!")
}
隐式方法增强
下面案例中Student
只用playGame
方法
class Student(val name:String) {
def study():Unit={
println("学生:"+name+" 学习..")
}
}
object UserImplicts{
implicit class StudentImplicts(stu:Student){
def playGame():Unit={
println("学生 "+stu.name+" 玩游戏")
}
}
}
object Student{
import UserImplicts._
def main(args: Array[String]): Unit = {
val s=new Student("张三")
s.study
s.playGame
}
}
Scala 泛型
<:
上边界限定
trait Keeper[U <: Animal]{
def keep(a:U);
}
表示Keeper的实现类只能饲养Animal以及Animal的子类
>:
下边界限定
trait Keeper[U >: Dog]{
def keep(a:U);
}
表示Keeper的实现类只能饲养Dog或者Dog的父类
<%
视图限定
视图限定将会在后续版本移除,主要意思是指必须保证上下文中有能够提供一个隐式转换T <% U
能够将T隐式转为U类型,如下所示要求上下文中能够尝试将一个Int类型隐式转换为Student类型。保证真个上下文中可以将一个Int类型看成是Student类型。
implicit def str2Stu(v:Int):Student={
new Student(v,"zhangsan")
}
def getStu[Int <% Student](v:Int):String={
v.name
}
T:A
上下文绑定
表示上下文中必须存在这种隐式值A[T]
隐式值,否则程序编译出错.这样可以在上下文中还没有隐式值得时候确保方法能编译成功。
class Student[T] {
def showMessage(msg:T):Unit={
msg match {
case x:String => println("name:"+x)
case x:Int => println("age:"+x)
case _ => println("不知道")
}
}
}
def sayInfomation[T:Student](msg:T):Unit={
var v=implicitly[Student[T]]
v.showMessage(msg)
}
implicit val s1=new Student[String]()
sayInfomation("张三")
+A协变
class Covariant[+T](t:T){}
val cov = new Covariant[Dog](new Dog("小狗"))
val cov2:Covariant[Animal] = cov
-A逆变
class Covariant[-T](t:T){}
val cov = new Covariant[Animal](new Animal("动物"))
val cov2:Covariant[Dog] = cov
A不变
class Covariant[T](t:T){}
val cov = new Covariant[Animal](new Animal("动物"))
val cov2:Covariant[Animal] = cov