大数据8_10_Scala异常&隐式转换

12 异常

  • Scala中的异常不区分所谓的编译时异常和运行时异常
  • 也无需显示抛出方法异常,所以Scala中没有throws关键字。

scala中异常的处理方式类似于模式匹配,如果异常类型没有匹配成功,也不会发生MatchError,只是将异常直接报给了JVM

12.1 java中的异常:

try {
    int a = 10;
    int b = 0;
    int c = a / b;
} catch (ArithmeticException e){
    // catch时,需要将范围小的写到前面
    e.printStackTrace();
} catch (Exception e){
    e.printStackTrace();
} finally {
    System.out.println("finally");
}

12.2 scala中的异常

object ScalaException {
    def main(args: Array[String]): Unit = {
        try {
            var n= 10 / 0
        }catch {
            case ex: ArithmeticException=>{
                // 发生算术异常
                println("发生算术异常")
            }
            case ex: Exception=>{
                // 对异常处理
                println("发生了异常1")
            }
        }finally {
            println("finally")
        }
    }
}

12.3 Java中的finally和return

public class FinallyTest {
    public static void main(String[] args) {
        System.out.println(test());	// 结果为1
    }

    public static int test(){
        int i = 0;
        try {
            return i++;
        }finally {
            return i++;
        }
    }
}
public class FinallyTest {
    public static void main(String[] args) {
        System.out.println(test());		//结果为0
    }

    public static int test(){
        int i = 0;
        try {
            return i++;
        }finally {
            i++;
        }
    }
}

13 隐式转换

13.1 隐式转换简介

什么是隐式转换?

其实之前学的自动类型转换,精度小类型可以自动转换成精度大的类型,由编译器自动完成的操作,就叫做隐式转换。

Scala在程序编译错误时,可以通过隐式转换中类型转换机制,进行二次编译。

将本身无法编译通过的代码通过类型转换后编译通过。

在相同作用域内,如果有相同的转换规则,转换规则的名字不同也会出错。

13.2 隐式函数

什么是隐式函数?

使用implicit关键字修饰的函数,称为隐式函数,可以被编译器在编译时使用。

就比如说原来一个函数的参数是一个Int类型,现在想修改这个参数类型为Double,那么就可以使用隐式函数,在编译的时候去自动查找这个编译规则。

object TestTransform_review {
  def main(args: Array[String]): Unit = {
    // 2 implicit声明一个隐式函数,将Double => Int
    implicit def intToDouble(age: Double) : Int = {
      age.toInt
    }
    test(13)
    // 1 当传入一个double类型的参数编译就无法通过~
    // 3 这样传入一个double类型的参数,编译就能通过了~ 
    //程序已经编译出现错误,编译器会尝试在指定范围内查找指定的转换规则
    //Double => Int,自动应用这个规则,让错误的程序可以编译通过
    //将这个操作称之为二次编译,这个转换是由编译器自动完成的,所以称为隐式转换  
    test(29.12)
  }
  def test(age : Int) ={
    println(age)
  }
}
实例操作

之前使用动态混入可以实现对功能的扩展。使用隐式函数也可以~

object TestTransform_review_1 {
  def main(args: Array[String]): Unit = {
//    //方式1 使用动态混入,添加新的功能
//    val user = new User with updateUser
//    user.insertUser()
//    user.updateUser()

    //方式2 使用隐式函数,添加新的功能
    //定义一个隐式函数,将User转换成UserExt
    implicit def transform(user: User) : UserExt = {
      new UserExt()
    }
    val user = new User
    user.insertUser()
    user.updateUser()
    //编译出现错误 -> 隐式转换规则
    //所谓的隐式转换其实就是通过类型的转换实现编译操作
    //如果在同一个作用域范围内,有相同类型的多个转换规则,那么会发生错误
    
  }
  //声明一个含有新功能的类。
  class UserExt(){
    def updateUser() = {
      println("updateUser----")
    }
  }

//  //声明一个trait特征,实现新的功能
//  trait updateUser {
//    def updateUser() = {
//      println("updateUser....")
//    }
//  }
  class User(){
    def insertUser(): Unit ={
      println("insertUser....")
    }
  }
}

13.3 隐式参数 & 隐式变量

什么是隐式参数?

隐式参数就是告诉编译器,这个参数有可能会改。

object TestTransform_review_2 {
  def main(args: Array[String]): Unit = {
    //1 定义一个regUser(),参数password含有默认值000000
    //3 当知道这个参数有可能会改,可以使用隐式变量,implicit
    def regUser(implicit password : String = "000000") = {
      println(password)
    }
    //4 给隐式变量赋值
    implicit var pwd = "666666"
    regUser()   //000000
    //2 这个时候如果想修改密码,可以直接传入新的密码
    regUser("123123")   //123123
    //5 隐式参数不需要传递参数,也不需要写参数列表
    //如果使用小括号,那么隐式变量不起作用
    regUser   //666666
  }
}

13.4 隐式类

在Scala2.10后提供了隐式类,可以使用implicit声明类,隐式类非常强大,同样可以扩展类的功能,在集合的数据处理中,隐式类发挥了重要的作用。

  • 其所带的构造参数有且只能有一个

  • 隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是顶级的。

object ScalaImplicit {
    def main(args: Array[String]): Unit = {
        val emp = new Emp()
        emp.insertUser()
    }
    class Emp {
    }
    implicit class User( emp : Emp) {
        def insertUser(): Unit = {
            println("insert user...")
        }
    }
}

13.5 隐式机制

所谓的隐式机制,就是一旦出现编译错误时,编译器会从哪些地方查找对应的隐式转换规则

Ø 当前代码作用域

Ø 当前代码上级作用域

Ø 当前类所在的包对象

Ø 当前类(对象)的父类(父类)或特质(父特质)

其实最直接的方式就是直接导入。

image-20201119150817342

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最佳第六六六人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值