Scala隐式(Implicit)

隐式(implicit)


隐式的意义所在

隐式转换让代码具有简洁性,但是降低了可读性。事实上它故意省略了一些代码,让机器自我推断。
Scala在面对编译出现类型错误时,提供了一个由编译器自我修复的机制,编译器试图去寻找一个隐式implicit的转换方法,转换出正确的类型,完成编译。

简单示例

package implicit_test

object a_implicit_test {
    def foo(msg: String): Unit = println(msg)

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

    //    提供了一个转换函数,从而使机器有了推断的依据,如果注释此代码,则foo(2)则会报错
    implicit def intToString(i: Int): String = i.toString
}

隐式包含:隐式参数、隐式转换类型、隐式类


隐式参数

我们定义了一个隐式值,不论是在外部定义(default_value),还是在函数体本身参数中定义(name),隐式的值可以传参数也可以不传,在不传参数时它将使用隐式值,传了参数则使用参数。

package implicit_test

object b_implicit_test {
    // 定义一个隐式值,此值在示例方法一中使用到
    implicit val default_value: Int = 5

    // 示例方法一
    def add(x: Int)(implicit y: Int): Unit = {
        println("相加值为 : " + (x + y).toString)
    }

    // 示例方法二
    def sayHello(implicit name: String = "scala"): Unit = {
        println(s"hello $name")
    }

    def main(args: Array[String]): Unit = {
        /*
            我们定义了一个隐式值,不论是在外部定义(default_value),还是在方法体本身参数中定义(name),隐式的值可以传参数也可以不传
            在不传参数时它将使用隐式值,传了参数则使用参数
        */

        add(10)
        add(100)(20)

        sayHello
        sayHello("aaa")
    }
}

隐式转换

当需要一种类型但是类型匹配又不对应时,编译器开始寻找上下文中的隐式转换;在如下示例中,编译器需要一个能够把double转化成int的函数或者方法;它将优先查找函数,如果没有再去找方法,没找到则会报错。

package implicit_test

object c_implicit_test {

    // 定义一个隐式方法 (method)
    implicit def doubleToInt1(double: Double): Int = {
        println("-------调用方法doubleToInt1-------")
        double.toInt
    }

    // 定义一个隐式函数 (funcion)
    implicit val doubleToInt2 = (double: Double) => {
        println("-------调用函数doubleToInt2-------")
        double.toInt
    }


    // 本身temp值为2020.10,则该值不为int类型,所以编译器开始寻找上下文中的隐式转换,一个能够把double转化成int的函数或者方法;优先查找函数,如果没有再去找方法。
    def main(args: Array[String]): Unit = {
        val temp: Int = 2020.10
        println(s"结果 : $temp")
    }
}

隐式类

定义隐式类,只能在静态对象(Object XXX)中使用

package implicit_test

import java.io.File
import scala.io.Source

object d_implicit_test {

    implicit class Read(file: File) {
        def readFile: String = Source.fromFile(file).mkString

        def fileIsEmpty: Boolean = Source.fromFile(file).isEmpty

        def fileLineCount: Int = Source.fromFile(file).getLines().length
    }

    def main(args: Array[String]): Unit = {
        val file = new File("E:\\Projects\\scala_test\\src\\main\\resources\\temp")
        val check = file.fileIsEmpty
        println(s"文件是否为空 : $check")

        val lineCount = file.fileLineCount
        println(s"文件行数 : $lineCount")

        val content = file.readFile
        println(s"读取内容\n$content")
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值