我们有时需要类A具有类B的方法,可以自定义一个隐式转换,将类A转换为类B,在引入这个隐式转换的作用域,使用类A就相当于使用了类B,
这样就达到了增强类A功能的目的。类似于装饰模式。
-
class RichFile(val file:File){
-
def read = Source.fromFile(file.getPath()).mkString
-
}
-
-
object Context{
-
implicit def file2RichFile(file:File)= new RichFile(file) //File -> RichFile,必须有implicit关键字
-
}
-
-
object Hello_Implicit_Conversions {
-
-
def main(args: Array[String]) {
-
import Context.file2RichFile //在当前作用域引入隐式转换
-
println(new File("D:\\hello.txt").read) //File本身是没有read方法的,需要隐式转换为自定义的RichFile
-
}
-
}
隐式参数,最直观的是,参数前面有implicit关键字,编译器会在作用域范围内查找谁是implict类型的值,如果有,则作为缺省值。
-
object Context_Implicits{
-
implicit val default:String = "Flink" //存在一个隐式值
-
}
-
-
object Param{
-
def print(content:String)(implicit language:String){
-
println(language+":"+content)
-
}
-
}
-
object Implicit_Parameters {
-
-
def main(args: Array[String]) {
-
Param.print("Spark")("Scala")
-
-
import Context_Implicits._ //从作用域范围内或者Object伴生对象中查找隐式参数
-
Param.print("Hadoop") //使用隐式参数
-
}
-
}
隐式参数下的隐式转换
object Implicit_Conversions_with_Implicit_Parameters {
def main(args: Array[String]) {
def bigger[T](a: T, b: T)(implicit ordered: T => Ordered[T]) //将匿名函数赋值给ordered变量,该隐式参数将T类型转换为Ordered[T]类型
= if (a > b) a else b //Ordered实现了<, >等
println(bigger(4,3))
println(bigger(4.2,3))
println(bigger("Spark","Hadoop"))
}
}
上下文界定中的隐式参数
class Pair_Implicits[T: Ordering](val first: T, val second: T){ //Ordering是泛型,上下文界定说明,只要存在T:Ordering ,就会存在一个隐式值Ordering[T]
def bigger(implicit ordered: Ordering[T]) =
if (ordered.compare(first, second) > 0) first else second
}
class Pair_Implicitly[T: Ordering](val first: T, val second: T){
def bigger =if (implicitly[Ordering[T]].compare(first, second) > 0) //implicitly提取出运行时上下文界定的实例
first else second
}
class Pair_Implicitly_Odereded[T: Ordering](val first: T, val second: T){
def bigger ={
import Ordered._
if (first > second) first else second //将Ordering[T]转换为Ordered[T],可以直接使用>
}
}
object Context_Bounds_Internals {
def main(args: Array[String]){
println(new Pair_Implicits(7, 9).bigger)
println(new Pair_Implicitly(7, 9).bigger)
println(new Pair_Implicitly_Odereded(7, 9).bigger)
}
}
隐式类:对类的功能增强
-
object Context_Helper{
-
implicit class FileEnhancer(file : File){
-
def read = Source.fromFile(file.getPath).mkString
-
}
-
implicit class Op(x:Int){
-
def addSAP(second: Int) = x + second
-
}
-
}
-
object Implicits_Class {
-
def main(args: Array[String]){
-
import Context_Helper._
-
println(1.addSAP(2))
-
println(new File("E:\\Test.txt").read)
-
-
}
-
}
隐式对象
-
abstract class Template[T] {
-
def add(x: T, y: T): T
-
}
-
abstract class SubTemplate[T] extends Template[T] {
-
def unit: T
-
}
-
object Implicits_Object {
-
-
def main(args: Array[String]) {
-
implicit object StringAdd extends SubTemplate[String] {
-
override def add(x: String, y: String) = x concat y
-
override def unit: String = ""
-
}
-
implicit object IntAdd extends SubTemplate[Int] {
-
override def add(x: Int, y: Int) = x + y
-
override def unit: Int = 0
-
}
-
def sum[T](xs: List[T])(implicit m: SubTemplate[T]): T = //m为隐式对象,根据T的具体类型引入相应的隐式对象
-
-
if (xs.isEmpty) m.unit
-
else m.add(xs.head, sum(xs.tail))
-
-
println(sum(List(1, 2, 3, 4, 5))) //引入IntAdd隐式对象
-
println(sum(List("Scala", "Spark", "Kafka"))) //引入StringAdd隐式对象
-
-
}
-
-
}
隐式转换内幕
-
class RicherFile(val file:File){
-
def read = Source.fromFile(file.getPath()).mkString
-
}
-
-
class File_Implicits( path: String) extends File(path)
-
object File_Implicits{
-
implicit def file2RicherFile(file:File)= new RicherFile(file) //File -> RicherFile
-
}
-
-
object Implicits_Internals {
-
def main(args: Array[String]) {
-
-
//因为类可以访问伴生对象里的所有内容,所以这里不需要import
-
println(new File_Implicits("E:\\Test.txt").read) //当前作用域没有import隐式参数,尝试从类的伴生对象中查找
-
}
-
}
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28912557/viewspace-1993997/
,如需转载,请注明出处,否则将追究法律责任。