scala 隐式详解(implicit关键字)
掌握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关键字)的更多相关文章
- Scala 隐式(implicit)详解
文章正文 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码. 1.Spark 中 ...
- scala 隐式转换
先参考这篇文章:http://www.jianshu.com/p/a344914de895 package com.test.scalaw.test /** * scala隐式转换 */ object ...
- Scala进阶之路-Scala函数篇详解
Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...
- windows scala helloworld例子详解
[学习笔记] windows scala helloworld例子详解: 在操作系统中,我们的Test3.scala会生成Test3.class,然后class文件被虚拟机加载并执行, 这一点和jav ...
- 21.C++- "++"操作符重载、隐式转换之explicit关键字、类的类型转换函数
++操作符重载 ++操作符分为前置++和后置++,比如: ++a; a++; ++操作符可以进行全局函数或成员函数重载 重载前置++操作符不需要参数 重载后置++操作符需要一个int类型的占位参数 ...
- Python 推导式详解
各种推导式详解 推导式的套路 之前我们已经学习了最简单的列表推导式和生成器表达式.但是除此之外,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. ...
- 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 ...
- Python推导式详解,带你写出比较精简酷炫的代码
Python推导式详解,带你写出比较精简酷炫的代码 前言 1.推导式分类与用法 1.1 列表推导 1.2 集合推导 1.3 字典推导 1.4 元组推导?不存在的 2.推导式的性能 2.1 列表推导式与 ...
- Scala隐式参数
Scala方法可以具有隐式参数列表,由参数列表开头的implicit关键字标记.如果参数列表中的参数没有像往常一样传递,Scala将查看它是否可以获得正确类型的隐式值,如果可以,将自动传递. Scal ...
随机推荐
- 使用Ajax和JSON实现注册时候验证用户名是否存在的功能
功能实现的思路:当通常一个网站需要注册用户信息的时候,往往会让用户起一个名字,但一般要求这个用户名称是不能重复的,为了判断新注册的用户填写的用户名是否已经存在,需要对填写的用户名称进行判断,实际项目开 ...
- hihocoder1712 字符串排序(思维)
https://hihocoder.com/problemset/problem/1712 感觉解法呼之欲出,却出不来.. 一个很好的思路是,根据新的顺序表,把给定的n组字符串换成旧表对应的字符,然后 ...
- set non-stop on
# Enable the async interface. set target-async 1 # If using the CLI, pagination breaks non-stop. set ...
- MySQL优化之like关键字
1.%号不放最左边 无法使用索引了,开头是不确定的,MySQL也无法进行优化了,只能扫描表了. 2.使用覆盖索引 如果业务需要%就放开头我们也没办法,一般情况需求都是这样的,毕竟优化还是为业务服务的. ...
- [web 前端] mobx教程(一)-mobx简介
opy from : https://blog.csdn.net/smk108/article/details/84777649 Mobx是通过函数响应式编程使状态管理变得简单和可扩展的状态管理库.M ...
- MySQL体系结构图详解
体系结构图如下: 连接层 思想为解决资源的频繁分配﹑释放所造成的问题,为数据库连接建立一个“缓冲池”.原理预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕 ...
- Javascript正则表达入参是null
今天群友问了一个问题,如下的执行结果是什么? var reg = /^[a-z0-9\u4e00-\u9fa5]{0,15}$/; console.log(reg.test(null)); // tr ...
- go-ehtereum编译:
git clone https://github.com/ethereum/go-ethereum.git cd go-ethereum && git checkout make ge ...
- 企业和个人都需要的终极跨平台全端解决方案 UniApp
相信大家在平时开发过程中都会遇到这两类问题: 很多中小型企业要快速开发一个产品,这个产品至少需要覆盖平台范围为:ios.Android.web/H5.微信/支付宝小程序,那么需要的投入的人力成本.时间 ...
- Intel Fortran 调用Delphi编制的DLL
module link_cont interface subroutine I_FileOpenCont (ncase,ndata,lpool,xfiles) integer(kind=) :: nc ...