Scala实战高手****第16课:Scala implicits编程彻底实战及Spark源码鉴赏
隐式转换:当某个类没有具体的方法时,可以在该类的伴生对象或上下文中查找是否存在隐式转换,将其转换为可以调用该方法的类,通过代码简单的描述下 一:隐式转换 1、定义类Man class Man(val name: String) 2、定义类SuperMan,并在类中定义一个方法 class SuperMan(val name: String) { def makeMiracles = println(this.name + " is super man!") } 3、在main方法中实例化man类,并调用makeMiracles方法,这时编译报错,提示man中没有这样的方法 val man = new Man("Scala") man.makeMiracles // 编译报错,提示man中无这样的方法 4、这时候我们就可以通过隐式转换的方式将man转换为SuperMan,这时候就可以调用makeMiracles object Man { //隐式转换 implicit def manToSuperMan(man: Man) = new SuperMan(man.name) } 完整代码: class Man(val name: String) class SuperMan(val name: String) { def makeMiracles = println(this.name + " is super man!") } object Man { //隐式转换 implicit def manToSuperMan(man: Man) = new SuperMan(man.name) } def main(args: Array[String]): Unit = { val man = new Man("Scala") man.makeMiracles } 二:隐式参数 简单看下代码: def talk(name: String)(implicit content: String) { println(name + ":" + content) } 这里的content就是定义为隐式参数,在调用的时候如果定义了隐式变量,则可以不传content参数 implicit val content = "Money" talk("Spark") //如果上下文没有定义隐式变量,则需传两个参数,也可以传两个参数进行覆写隐式值 talk("Spark")("Scala") //Scala会覆盖Money 三:隐式类 //隐式类 implicit class sum(x: Int) { def add(y: Int) = x + y } //隐式类 println(3.add(2)) //本身3是没有add这样的方法,通过隐式类转换,就可以实现这样的功能,主要是看上下文中是否有参数为Int类型的隐式转换操作 四:隐式对象 示例代码: abstract class Template[T] { def add(x: T, y: T): T def unit: T } //隐式对象 object ScalaImplicitObject { implicit object StringAdd extends Template[String] { override def add(x: String, y: String) = x.concat(y) override def unit: String = "" } implicit object IntAdd extends Template[Int] { override def add(x: Int, y: Int) = x + y override def unit: Int = 0 } } 定义sum方法 def sum[T](list: List[T])(implicit t: Template[T]): T = { if (list.isEmpty) t.unit else t.add(list.head, sum(list.tail)) //递归调用sum } 在main方法中调用 import com.dt.scala.ScalaImplicitObject._ //导入隐式转换 println(sum(List(1 to 100: _*))) println(sum(List("Spark", "-", "Scala")))