第28课:Scala隐式转换内幕实践解密

2016-08-21  本文已影响0人  fatj

其实隐式转换有几种类型:隐式参数,隐式转换,隐式对象,和隐式类

首先看一下Scala的作用域

隐式参数冲突的情况:

object Implicits {
  implicit val content="Scala"
}

object ImplicitsMsg {
  implicit val content="ScalaMsg"
}

object ImplicitAdance extends App {

  def printContent(implicit content:String)=println(content)
//  implicit val msg="Spark" //有两个隐式参数的时候,就会出现冲突
  import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
  //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
  import ImplicitsMsg._
  printContent

}

非隐式参数不冲突,明确指定的导入方式优先级更高

object Implicits {
  val content="Scala"
}

object ImplicitsMsg {
  val content="ScalaMsg"
}

object ImplicitAdance extends App {

  def printContent(implicit content:String)=println(content)
//  implicit val msg="Spark" //有两个隐式参数的时候,就会出现冲突
  import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
  //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
  import ImplicitsMsg._
  printContent(content)

}

当然,当前作用域的优先级还是最高的:

object Implicits {
  val content="Scala"
}

object ImplicitsMsg {
  val content="ScalaMsg"
}

object ImplicitAdance extends App {

  def printContent(implicit content:String)=println(content)
  val content="Spark" //有两个隐式参数的时候,就会出现冲突
  import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
  //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
  import ImplicitsMsg._
  printContent(content)

}

另外一个例子说明:

object Implicits {
  implicit val content="Scala"
}

//object ImplicitsMsg {
//  val content="ScalaMsg"
//}

object ImplicitAdance extends App {

  def printContent(implicit content:String)=println(content)
  val content="Spark" //有两个隐式参数的时候,就会出现冲突
  import Implicits.content //当你导入一个类的时候,连伴生对象的成员也会导入进来,
  //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
//  import ImplicitsMsg._
  printContent(content)

}

隐式转换能起到增强功能的作用

class RichFile(val file:File) {
  def dtSpark=println("dySpark:"+file.getName)
}

object Implicits {
  implicit val content="Scala"
  implicit def int2String(x:Int)=x.toString()
  implicit def fileToRichFile(file:File)=new RichFile(file)
  implicit def richFileToFile(richFile:RichFile)=richFile.file //一般还会重新转换回来
}

object ImplicitAdance extends App {

  def printContent(implicit content:String)=println(content)
  val content="Spark" //有两个隐式参数的时候,就会出现冲突
  import Implicits._ //当你导入一个类的时候,连伴生对象的成员也会导入进来,
  //当明确指定需要导入哪个属性的时候,优先级会更高(当然不是隐式参数的情况)
//  import ImplicitsMsg._
  printContent(content)

  printContent(100)

  (new File(".")).dtSpark

}

这是很有用的,例如我们只想在某一时刻用到一个类的功能,但不是一直都在使用,这时候使用隐式转换是非常有用的
一般来说,隐式转换都会放到伴生对象中,这样有利于组织代码,例如Spark的RDD就是一个很好的例子
在设计隐式转换的时候必须注意冲突的问题
找出当前作用域中隐式参数的值

println(implicitly[String])

总结隐式转换的顺序:1.上下文 2.伴生对象 3.相关类型的伴生对象 4.导入

归纳总结:1.隐式转换的几种类型
2.隐式转换查找的顺序
3.几个例子
4.隐式转换的巨大作用和最佳实践
5.implicitly[String]的作用


cccc.png
上一篇下一篇

猜你喜欢

热点阅读