scala语法(五)

隐式转换、隐式函数,隐式值

隐式转换

高精度-> 低精度 需要强制转换
隐式转换函数是以implicit关键字声明的带有单个参数的函数。这种函数将会自动应用,将值从一种类型转换为另一种类型。
使用隐式函数可以优雅的解决数据类型转换。

  1. 隐式转换函数的函数名可以是任意的,隐式转换与函数名称无关,只与函数签名(函数参数类型和返回值类型)有关。
  2. 隐式函数可以有多个(即:隐式函数列表),但是需要保证在当前环境下,只有一个隐式函数能被识别
object Test {def main(args: Array[String]): Unit = {implicit def f1(d: Double): Int = {d.toInt}//   implicit def f2(d: Double): Int = {//     d.toInt//   } 同时出现会报错,下面不知道调用哪个隐式函数val num: Int = 3.5println(num)}
}

隐式转换丰富类库功能

如果需要为一个类增加一个方法,可以通过隐式转换来实现。(动态增加功能)比如想为MySQL类增加一个delete方法

object ImplicitDemo02 {def main(args: Array[String]): Unit = {//隐式函数implicit def addDelete(mySQL: MySQL): DB = {new DB}//创建MySQL对象val mySQL = new MySQLmySQL.delete() //底层(编译器做的转换)是这样的: addDelete$1(mySQL).delete()mySQL.batchDelete() //底层(编译器做的转换)是这样的: addDelete$1(mySQL).batchDelete()}
}//类-insert
class MySQL {def insert(): Unit = {println("insert")}}//类 DB-delete
class DB {def delete(): Unit = {println("delete...")}def batchDelete(): Unit = {println("batchDelete...")}
}
delete...
batchDelete...

隐式值

隐式值也叫隐式变量,将某个形参变量标记为implicit,所以编译器会在方法省略隐式参数的情况下去搜索作用域内的隐式值作为缺省参数。

object ImplicitValDemo01 {def main(args: Array[String]): Unit = {//这里的 str1就是隐式值  implicit val str1: String = "jack"//说明//1.implicit name: String 就是一个隐式参数//2.当调用hello的时候,没有传入实参,则编译器会自动的将隐式值关联到name上def hello(implicit name: String): Unit = {println(name + " hello")}hello //用到隐式值 底层  hello$1(str1)}
}
jack hello

隐式类

在scala2.10后提供了隐式类,可以使用implicit声明类,隐式类的非常强大,同样可以扩展类的功能,比前面使用隐式转换丰富类库功能更加的方便,在集合中隐式类会发挥重要的作用。

  1. 其所带的构造参数有且只能有一个
  2. 隐式类必须被定义在“类”或“伴生对象”或“包对象”里,即隐式类不能是 顶级的(top-level objects)
  3. 隐式类不能是case class(case class在后续介绍 样例类)
  4. 作用域内不能有与之相同名称的标识符
object ImplicitClass {def main(args: Array[String]): Unit = {//一个隐式类, 可以返回一个隐式类的实例,然后就可以调用隐式类的方法implicit class DB1(val m: MySQL1) {def addSuffix(): String = { //方法m + " scala"}def sayHi(): Unit = {println("sayHi..")}def sayHello(): Unit = {println("hello")m.sayOk()}}val mySQL = new MySQL1mySQL.sayOk() //// 1.底层 DB1$1(mySQL).addSuffix()// 2. DB1$1(mySQL) 返回的是 :ImplicitClass$DB1$2 实例// 3. 通过返回的  ImplicitClass$DB1$2实例.addSuffix()println(mySQL.addSuffix()) //DB1$1(mySQL).addSuffix()mySQL.sayHi()mySQL.sayHello()}
}class MySQL1 { //普通类def sayOk(): Unit = {println("sayOk")}
}