热门标签 | 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等大数据技术干货及相关技术资讯

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



觉得文章不错?扫描关注






推荐阅读
  • 什么是大数据lambda架构
    一、什么是Lambda架构Lambda架构由Storm的作者[NathanMarz]提出,根据维基百科的定义,Lambda架构的设计是为了在处理大规模数 ... [详细]
  • 在计算机领域,数据仓库(DW或DWH),是一个用于报告和数据分析的零碎,被认为是商业智能的一个外围组成部分。它将以后和历史数据存储在一个中央,为整个企 ... [详细]
  • 目录摘要SQL的现在NoSQL,NotOnlySQL要分布式,也要SQL总结引用摘要毫不夸张的说,关系数据库是企业软件系统的核心,企业形形色色信息行为的背后,都有关系数据库的支撑。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 讨伐Java多线程与高并发——MQ篇
    本文是学习Java多线程与高并发知识时做的笔记。这部分内容比较多,按照内容分为5个部分:多线程基础篇JUC篇同步容器和并发容器篇线程池篇MQ篇本篇 ... [详细]
  • 你知道Kafka和Redis的各自优缺点吗?一文带你优化选择,不走弯路 ... [详细]
  • 马蜂窝数据总监分享:从数仓到数据中台,大数据演进技术选型最优解
    大家好,今天分享的议题主要包括几大内容:带大家回顾一下大数据在国内的发展,从传统数仓到当前数据中台的演进过程;我个人认为数 ... [详细]
  • 我这几年踩过的十个坑,每一条都是血泪教训
    “阅读本文大概需要3分钟。”一、不记录程序部署在哪里“我:他妈的,这个程序明明一直在正确产生日志,可它到底运行在哪里?怎么我 ... [详细]
  • 背景信息公司目前有40人,研发人员占比60-70% ... [详细]
  • 技术方案:Spark、kafka、opentsdb、Yahoo的egads模型静态训练:采用两种算法进行模型的训练:指数移动平均和HotWinters,模型一天训练一次,即每天0点开始训练, ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • springboot基于redis配置session共享项目环境配置pom.xml引入依赖application.properties配置Cookie序列化(高版本不需要)测试启 ... [详细]
  • 我知道那里有很多类似的问题,但我还没有找到任何与我的场景完全匹配的问题,所以请不要对重复标志太满意。我正在使用Spark3.0.1在AzureDatabrick ... [详细]
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社区 版权所有