掌握implicit的用法是阅读spark源码的基础,也是学习scala其它的开源框架的关键,implicit 可分为:

  • 隐式参数
  • 隐式转换类型
  • 隐式调用函数

1.隐式参数

当我们在定义方法时,可以把最后一个参数列表标记为implicit,表示该组参数是隐式参数。一个方法只会有一个隐式参数列表,置于方法的最后一个参数列表。如果方法有多个隐式参数,只需一个implicit修饰即可。 当调用包含隐式参数的方法是,如果当前上下文中有合适的隐式值,则编译器会自动为改组参数填充合适的值。如果没有编译器会抛出异常。当然,标记为隐式参数的我们也可以手动为该参数添加默认值。def foo(n: Int)(implicit t1: String, t2: Double = 3.14)

scala > def calcTax(amount: Float)(implicit rate: Float): Float = amount * rate
scala > implicit val currentTaxRate = 0.08F
scala > val tax = calcTax(50000F) // 4000.0

如果编译器在上下文没有找到第二行代码会报错

2.隐式地转换类型

使用隐含转换将变量转换成预期的类型是编译器最先使用 implicit 的地方。这个规则非常简单,当编译器看到类型X而却需要类型Y,它就在当前作用域查找是否定义了从类型X到类型Y的隐式定义
例子:

scala> val i: Int = 3.5 //直接报错
加上这句:
scala> implicit def double2Int(d: Double) = d.toInt
再运行,没报错
scala> val i: Int = 3.5  //i=3

3.隐式调用函数

隐式调用函数可以转换调用方法的对象,比如但编译器看到X .method,而类型 X 没有定义 method(包括基类)方法,那么编译器就查找作用域内定义的从 X 到其它对象的类型转换,比如 Y,而类型Y定义了 method 方法,编译器就首先使用隐含类型转换把 X 转换成 Y,然后调用 Y 的 method。
例子:

class SwingType{
  def  wantLearned(sw : String) = println("兔子已经学会了"+sw)
}
object swimming{
  implicit def learningType(s : AminalType) = new SwingType
}
class AminalType
object AminalType extends  App{
  import com.mobin.scala.Scalaimplicit.swimming._
  val rabbit = new AminalType
    rabbit.wantLearned("breaststroke")         //蛙泳
}

上例中编译器在rabbit对象调用时发现对象上并没有wantLearning方法,此时编译器就会在作用域范围内查找能使其编译通过的隐式视图,找到learningType方法后,编译器通过隐式转换将对象转换成具有这个方法的对象,之后调用wantLearning方法

scala 隐式详解(implicit关键字)的更多相关文章

  1. Scala 隐式(implicit)详解

    文章正文 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码. 1.Spark 中 ...

  2. scala 隐式转换

    先参考这篇文章:http://www.jianshu.com/p/a344914de895 package com.test.scalaw.test /** * scala隐式转换 */ object ...

  3. Scala进阶之路-Scala函数篇详解

    Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...

  4. windows scala helloworld例子详解

    [学习笔记] windows scala helloworld例子详解: 在操作系统中,我们的Test3.scala会生成Test3.class,然后class文件被虚拟机加载并执行, 这一点和jav ...

  5. 21.C++- "++"操作符重载、隐式转换之explicit关键字、类的类型转换函数

    ++操作符重载 ++操作符分为前置++和后置++,比如: ++a;  a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 ...

  6. Python 推导式详解

    各种推导式详解 推导式的套路 之前我们已经学习了最简单的列表推导式和生成器表达式.但是除此之外,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. ...

  7. JSP——JavaServer Page中的隐式对象(implicit object)、指令(directive)、脚本元素(scripting element)、动作(action)、EL表达式

    目录 1.JSP概述 2.注释(comment) 2.1.JSP注释 2.2.HTML注释 3.隐式对象(implicit object) 3.1.隐式对象清单 3.2.request对象 3.3.o ...

  8. Python推导式详解,带你写出比较精简酷炫的代码

    Python推导式详解,带你写出比较精简酷炫的代码 前言 1.推导式分类与用法 1.1 列表推导 1.2 集合推导 1.3 字典推导 1.4 元组推导?不存在的 2.推导式的性能 2.1 列表推导式与 ...

  9. Scala隐式参数

    Scala方法可以具有隐式参数列表,由参数列表开头的implicit关键字标记.如果参数列表中的参数没有像往常一样传递,Scala将查看它是否可以获得正确类型的隐式值,如果可以,将自动传递. Scal ...

随机推荐

  1. eclipse Dynamic web module相关问题

    大致因为java的web系统有多种类型,比如静态的和动态的,然后动态的java web project要设置dynamic web module,也就是动态网页模型,他必须要喝对应的服务器搭配好了才能 ...

  2. linux操作之逻辑分区与交换分区篇

    作业一: 1)   开启Linux系统前添加一块大小为15G的SCSI硬盘 2)   开启系统,右击桌面,打开终端 3)   为新加的硬盘分区,一个主分区大小为5G,剩余空间给扩展分区,在扩展分区上划 ...

  3. lettcode笔记--Valid Parentheses

    20.Valid Parentheses Given a string containing just the characters '(', ')', '{', '}', '[' and ']', ...

  4. 开源流媒体服务器SRS学习笔记(3) - HTTPCallback实现安全认证

    按上回继续,安全论证是绝大多数应用的基本要求,如果任何人都能无限制的发布/播放视频,显然不适合.SRS中可以通过HTTPCallback机制来实现,参考下面的配置: ... vhost __defau ...

  5. ASP.NET Core托管和部署Linux实操演练手册

    一.课程介绍 ASP.NET Core 是一种全新的跨平台开源 .NET 框架,能够在 IIS.Nginx.Apache.Docker 上进行托管或在自己的进程中进行自托管. 作为一个.NET Web ...

  6. Python3 与 NetCore 基础语法对比(List、Tuple、Dict、Set专栏)

    Jupyter最新版:https://www.cnblogs.com/dotnetcrazy/p/9155310.html 在线演示:http://nbviewer.jupyter.org/githu ...

  7. ssh-keygen 基本用法

    ssh-keygen命令用于为"ssh"生成.管理和转换认证密钥,它支持RSA和DSA两种认证密钥. ssh-keygen(选项) -b:指定密钥长度: -e:读取openssh的 ...

  8. 关于jmeter命令行执行.jmx文件出现Error in NonGUIDriver java.lang.RuntimeException: Could not find the TestPlan c

     

  9. jvm实战-jvm调优

    jvm调优 jvm调优主要是内存管理方面的调优,包括各个代的大小,GC策略等. 代大小调优 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内 ...

  10. C# System.Collections.Generic.Dictionary

    using System; using System.Collections.Generic; public class Example { public static void Main() { / ...