Scala基石之隐式转换

Scala之隐式转换

隐式转换在Scala中无处不在,在默认的情况下Scala就会引入很多的包。

 

println(“a”)就相当于Predef._。

1 to 10 实际上是1.to 10,把一个int类型的对象转化成richInt了。

 

使用隐式转换对已有的功能进行增强

例1:

import java.io.File

import scala.io.Source

 

object ImplicitTest extends App{

  implicit class RichFile(from : File) {

    def read : String = Source.fromFile(from.getPath).mkString

  }

  val contents = new File("src/test.txt").read

  println(contents)  // 外面有橘色的加州阳光。

}

 

原本的Java的File是没有File方法的,但是我们自定义了一个显示类使得File中有了read方法。在SparkSQL中用的相当多。

 

例2:

implicit class IntWithTimes(x : Int) { // 构造函数是一个int

    def times[A] (f : => A) : Unit = { // 传入的参数是一个函数

      def loop(current : Int) : Unit = {

        if (current > 0) {

          f // 调用传入的函数

          loop(current - 1)

        }

      }

      loop(x) // 一定要调用它

    }

  }

  // 一般会放在不同的类中

  import ImplicitTest._

  10 times println("success")

 

例3:

在Scala中一个int类型的值能够赋值给double类型的原因就是因为,int 中有toDouble方法。下面模拟一下double类型赋值给int的隐式转换:

 

implicit def doubleToInt (x : Double) = x toInt

  var a:Int = 1

  var b:Double = 2

  a = b

  println(a) // 2

 

注意:

①在传入的参数为函数时会有如下的一些注意事项。

简单来说, => Unit是 传名函数, 只传入了一个表达式, 在调用时才会去执行, 使用 code调用() => 是传值函数, 传入的计算后的值, 使用 code() 调用。看起来像只是调用方式的不同而已。以下代码来自于https://www.cnblogs.com/wenbronk/p/7509676.html

 

package main.scala

 

/**

  * Created by wenbronk on 2017/9/12.

  */

object TestScala {

 

  def main(args: Array[String]): Unit = {

//    println( addInt(3, 5))

//    println(time())

    delayTime({

      println("2222");

      time()

    })

    delayTime2({

      println("333");

      time

    })

  }

 

  def delayTime2(t: () => Long): Unit = {

    println("执行...")

    println( t() )

    println("jiesu..")

  }

 

  def delayTime(t: => Long): Unit = {

    println("执行开始")

    println(t)

    println("执行结束")

  }

 

  def time() = {

    println("获取时间内, 单位为 纳秒")

    System.nanoTime()

  }

 

}

② 隐式类的构造函数只能带有一个非隐式参数。

 

implicit class Indexer[T] (collection : Seq[T], index : Int) // 不可以

implicit class Indexer[T] (collection : Seq[T])(implicit index : Int) // 可以

 

③ 在同一作用域中不能出现方法,对象,成员与隐式类同名。

 

隐式参数

在定义方法时,参数中可以有隐式参数。在传值的时候如果没有显式的传入隐式对象的时候那么编译器就会自动搜索作用域下的隐式对象。若还没有隐式对象那么就会抛出异常。

 

object ImplicitParam extends App{

  trait Adder[T] {

    def add (x : T, y : T) : T

  }

 

  implicit val a = new Adder[Int] {

    override def add (x : Int, y : Int) = {

      println(x + y)

      x + y

    }

  }

 

  def addTest(x : Int, y : Int)(implicit adder : Adder[Int]) = {

    adder.add(x,y)

  }

 

  addTest(1,2)

}

 

你可能感兴趣的:(Scala)