热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

每日一课:隐式参数

先回顾一下隐式对象的使用代码:**隐式对象*objectExample11_1

先回顾一下隐式对象的使用代码:

/*

*隐式对象

*/

object Example11_1 extends App{

  //定义一个trait Multiplicable

  trait Multiplicable[T] {

    def multiply(x: T): T

  }

  //定义一个隐式对象MultiplicableInt,用于整型数据的相乘

    implicit objectMultiplicableInt extends Multiplicable[Int] {

      def multiply(x: Int) =x*x

    }

  //定义一个隐式对象MultiplicableString,用于字符串数据的乘积

    implicit objectMultiplicableString extends Multiplicable[String] {

      def multiply(x: String)= x*2

    }

  //定义一个函数,函数具有泛型参数

  def multiply[T:Multiplicable](x:T) = {

    //implicitly方法,访问隐式对象

    val ev =implicitly[Multiplicable[T]]

    //根据具体的类型调用相应的隐式对象中的方法

    ev.multiply(x)

  }

  //调用隐式对象MultiplicableInt中的multiply方法

  println(multiply(5))

  //调用隐式对象MultiplicableString中的multiply方法

 println(multiply("5"))

}



在Example11_1代码中,我们在val ev =implicitly[Multiplicable[T]]代码中调用implicitly函数来确定最终的隐式对象,该函数也被定义在Predef对象中,现在让我们来下该函数的定义:

@inline def implicitly[T](implicit e: T) = e

可以看到implicitly函数中有一个参数implicit e: T同一般函数所不同的是参数e前面也使用了implicit关键字修饰我们称这种形式的参数为隐式参数。通过val ev = implicitly[Multiplicable[T]]可以看到,我们调用的时候并没有指定该隐式参数,那值是怎么传进行来的呢?这便是隐式参数的作用,前面提到函数def multiply[T: Multiplicable](x:T)要求在当前作用域存在一个类型为Multiplicable[T]隐式值或隐式对象,在调用该函数时具体的参数类型被确定,如调用multiply(5)时参数类型为Int,则会在当前作用域内查找类型为Multiplicable[T]的隐式值或隐式对象,此时MultiplicableInt满足要求,因此最终implicitly方法返回的对象为MultiplicableInt然后调用def multiply(x: String) = x*2方法得到最终结果。其实Example11_1中的multiply方法还可以利用隐式参数进行进一步简化,即将

//定义一个函数,函数具有泛型参数

  def multiply[T:Multiplicable](x:T) = {

    //implicitly方法,访问隐式对象

    val ev =implicitly[Multiplicable[T]]

    //根据具体的类型调用相应的隐式对象中的方法

    ev.multiply(x)

}

修改为

//使用隐式参数定义multiply函数

  def multiply[T:Multiplicable](x:T)(implicit ev:Multiplicable[T]) = {

      //根据具体的类型调用相应的隐式对象中的方法

    ev.multiply(x)

  }

完整代码如下:

/*

*隐式参数

*/

object Example11_2 extends App{

  //定义一个trait Multiplicable

  trait Multiplicable[T] {

    def multiply(x: T): T

  }

  //定义一个隐式对象MultiplicableInt用于整型数据的相乘

  implicit object MultiplicableInt extendsMultiplicable[Int] {

    def multiply(x: Int) = x*x

  }

  //定义一个隐式对象MultiplicableString用于字符串数据的乘积

  implicit object MultiplicableString extendsMultiplicable[String] {

    def multiply(x: String) = x*2

  }

  //使用隐式参数定义multiply函数

  def multiply[T:Multiplicable](x:T)(implicit ev:Multiplicable[T]) = {

      //根据具体的类型调用相应的隐式对象中的方法

    ev.multiply(x)

  }

  //调用隐式对象MultiplicableInt中的multiply方法

  println(multiply(5))

  //调用隐式对象MultiplicableString中的multiply方法

  println(multiply("5"))

}

代码运行结果与Example11_1相同,函数def multiply[T:Multiplicable](x:T)(implicit ev:Multiplicable[T])使用的隐式参数,它会在当前作用域内查找类型Multiplicable[T]的隐式对象,因此在执行multiply(5)时,由于泛型参数类型为Int,它便会在当前作用域内查找Multiplicable[Int]类型的隐式对象,只有implicit objectMultiplicableInt extends Multiplicable[Int]满足要求,因此会将MultiplicableInt赋值给ev,然后再调用def multiply(x: Int)= x*x执行最终计算。



Scala学习(公众微信号:ScalaLearning)每天为大家带来一点Scala语言、Spark、Kafka、Flink、AKKA等大数据技术干货及相关技术资讯

技术永无止境,勇攀高峰,一往直前!



觉得文章不错?扫描关注






推荐阅读
  • 从0到1搭建大数据平台
    从0到1搭建大数据平台 ... [详细]
  • 在第二课中,我们将深入探讨Scala的面向对象编程核心概念及其在Spark源码中的应用。首先,通过详细的实战案例,全面解析Scala中的类和对象。作为一门纯面向对象的语言,Scala的类设计和对象使用是理解其面向对象特性的关键。此外,我们还将介绍如何通过阅读Spark源码来进一步巩固对这些概念的理解。这不仅有助于提升编程技能,还能为后续的高级应用开发打下坚实的基础。 ... [详细]
  • 什么是大数据lambda架构
    一、什么是Lambda架构Lambda架构由Storm的作者[NathanMarz]提出,根据维基百科的定义,Lambda架构的设计是为了在处理大规模数 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • 技术日志:深入探讨Spark Streaming与Spark SQL的融合应用
    技术日志:深入探讨Spark Streaming与Spark SQL的融合应用 ... [详细]
  • 修复一个 Bug 竟耗时两天?真的有那么复杂吗?
    修复一个 Bug 竟然耗费了两天时间?这背后究竟隐藏着怎样的复杂性?本文将深入探讨这个看似简单的 Bug 为何会如此棘手,从代码层面剖析问题根源,并分享解决过程中遇到的技术挑战和心得。 ... [详细]
  • 在使用sbt构建项目时,遇到了“对象apache不是org软件包的成员”的错误。本文详细分析了该问题的原因,并提供了有效的解决方案,包括检查依赖配置、清理缓存和更新sbt插件等步骤,帮助开发者快速解决问题。 ... [详细]
  • Storm集成Kakfa
    一、整合说明Storm官方对Kafka的整合分为两个版本,官方说明文档分别如下:StormKafkaIntegratio ... [详细]
  • 深入理解Spark框架:RDD核心概念与操作详解
    RDD是Spark框架的核心计算模型,全称为弹性分布式数据集(Resilient Distributed Dataset)。本文详细解析了RDD的基本概念、特性及其在Spark中的关键操作,包括创建、转换和行动操作等,帮助读者深入理解Spark的工作原理和优化策略。通过具体示例和代码片段,进一步阐述了如何高效利用RDD进行大数据处理。 ... [详细]
  • 深入解析十大经典排序算法:动画演示、原理分析与代码实现
    本文深入探讨了十种经典的排序算法,不仅通过动画直观展示了每种算法的运行过程,还详细解析了其背后的原理与机制,并提供了相应的代码实现,帮助读者全面理解和掌握这些算法的核心要点。 ... [详细]
  • PHP编程语言中的标量数据类型及其种类详解 ... [详细]
  • 又给自己挖了一个坑跳进去。KafkaManager使用单例模型获取到一个producer,然而自己代码里用的时候加了一个using然后自己在做测试的时候,for循环加10条数据发送 ... [详细]
author-avatar
www
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有