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方法

时间: 2024-08-09 13:15:53

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

Scala隐式转化和并发编程

1.Scala隐式彻底详解 隐式转换 implicit ,可通过手动指定将某种类型的对象或者某种类转换成其他类型的类或者对象 形式:implicit def function 隐式函数.隐式参数.隐式对象.隐式类 隐式函数:指有implicit前置修饰的函数 Scala会根据上下文,利用隐式转换函数的签名主要是输入类型,在程序运行时利用隐式转换函数,将接受的隐式函数参数类型定义的对象自动升级转换成隐式转换后的对象.转换成另外一种对象返还,任务完成后重新转换为原来类型.如果调用对象没有要调用的方法

第5课:彻底精通Scala隐式转换和并发编程及Spark源码阅读

隐式转换函数implicit def function例如implicit def rddToPairRDDFunctions[K, V](rdd: RDD[(K, V)]) scala> class Person(val name: String)defined class Person scala> class Enginner(val name: String, val salary: Double) { | def code = println(name + " Coding

各种推导式详解

各种推导式详解 推导式的套路 之前我们已经学习了最简单的列表推导式和生成器表达式.但是除此之外,其实还有字典推导式.集合推导式等等. 下面是一个以列表推导式为例的推导式详细格式,同样适用于其他推导式. variable = [out_exp_res for out_exp in input_list if out_exp == 2] out_exp_res: 列表生成元素表达式,可以是有返回值的函数. for out_exp in input_list: 迭代input_list将out_exp

Scala隐式转换

概述 简单说,隐式转换就是:当Scala编译器进行类型匹配时,如果找不到合适的候选,那么隐式转化提供了另外一种途径来告诉编译器如何将当前的类型转换成预期类型.本文原文出处: http://blog.csdn.net/bluishglc/article/details/50866314 严禁任何形式的转载,否则将委托CSDN官方维护权益! 隐式转换有四种常见的使用场景: 将某一类型转换成预期类型 类型增强与扩展 模拟新的语法 类型类 语法 隐式转换有新旧两种定义方法,旧的定义方法指是的"impli

Scala隐式参数

Scala方法可以具有隐式参数列表,由参数列表开头的implicit关键字标记.如果参数列表中的参数没有像往常一样传递,Scala将查看它是否可以获得正确类型的隐式值,如果可以,将自动传递. Scala将查找这些参数的位置分为两类: 1.Scala在调用包含有隐式参数块的方法时,将首先查找可以直接访问的隐式定义和隐式参数(无前缀). 2.在所有伴生对象中查找与隐式候选类型相关的有隐式标记的成员. 1 package big.data.analyse.scala 2 3 /** 4 * Creat

scala 高级十八 scala隐式方法,隐式参数的实现和使用

摘要: 通过隐式转换,程序员可以在编写Scala程序时故意漏掉一些信息,让编译器去尝试在编译期间自动推导出这些信息来,这种特性可以极大的减少代码量,忽略那些冗长,过于细节的代码. 使用方式: 1.将方法或变量标记为implicit 2.将方法的参数列表标记为implicit 3.将类标记为implicit 隐式方法: package smart.iot import java.io.File import scala.io.Source class concealFunc(f:File) { d

大数据学习:Scala隐式转换和并发编程(DT大数据梦工厂)

很多Spark代码中使用了隐式转换.隐式参数.隐式类.隐式对象 如果不掌握,基本在读写复杂代码的时候读不懂 并发编程,怎么样进行高效并发,相互之间怎么通信,Spark这种分布式并发肯定非常重要 (Actor.Akka) ==========隐式转换函数============ 可以手动指定将某种类型的对象转换成其它类型的对象或者类 转换原因:假设制定好接口 比如File,我们想要File.dtSpark的方法,在JAVA中不行 如果在Scala里面我们可以进行升级,将File编程其它类型,就用之

Scala隐式转换类遇到的问题

今天练习Scala的隐式转换类遇到的一个问题,测试代码如下: object ImplcitTest { def main(args: Array[String]) { import Context._ val person1 = User("zhangsan") println(person1.getStr()) val filePath = Thread.currentThread.getContextClassLoader.getResource("test.txt&qu

记录: 一次解决整型溢出攻击(使用scala,隐式转换)

最近项目遇到一次整型溢出攻击 有一个功能,玩家购买num个物品. 每个物品花费14货币. 客户端限制玩家只能购买 1-9999个该物品. 但是某玩家通过技术手段,获得了客户端的运行权限. 于是发送协议购买该物品 306783379 个 于是服务器收到请求进行以下处理 val num = message.getInt("num") //获得客户端发送来的 306783379 val cost = num * produc.price  //这里没有校验物品的数量就直接计算总价了. 所以总