Implicits work like this: if you call a method on a Scala object, and the Scala compiler does not see a definition for that method in the class definition for that object, the compiler will try to convert your object to an instance of a class that does have that method defined
隐式转换是Scala类型系统的强大特性之一,使得静态类型动态化,为现有类库添加功能。Scala的隐式转换,有三种:
- 隐式函数
- 隐式参数
- 隐式类
隐式转换的规则:
- 如果代码无需隐式转换即可通过编译,则不会引入隐式转换
- 隐式转换只会匹配一次,即隐式转换至多发生一次
- 存在二义性的隐式转换报错,
在期望隐式转换发生作用的时候,必须告诉Scala编译器,隐式转换背后起作用的实现逻辑在哪里?这个实现逻辑称为作用域或者为上下文Context
一、隐式函数
增强一个类,添加本不存在的方法,implicit作用于函数,称之为隐式函数
package spark.examples.scala //假如Arithmetic是已有的类库中的类,仅仅提供add函数 class Arithmetic { def add(x: Int, y: Int): Int = { x + y } } //========================================= //下面是增强Arithmetic类,添加一个subtract方法 //========================================= class RichArithmetic(val arithmetic: Arithmetic) { def substract(x: Int, y: Int) = { x - y } } //转换的逻辑,隐式方法 object ArithmeticToRichArithmetic { //将Arithmetic转换为RichArithmetic //Arithmetic对象上可以直接调用RichArithmetic定义的方法 implicit def arithmeticToRichArithmetic(arithmetic: Arithmetic) = { new RichArithmetic(arithmetic) } } object ImplicitDemo { def main(args: Array[String]) { import ArithmeticToRichArithmetic._ //引用方法 val a = new Arithmetic println(a.add(11, 21)) println(a.substract(21,11)) //substract不属于Arithmetic } }
二、隐式参数:
package spark.examples.scala object ObjectA { def print(content: String)(implicit prefix : String) { println(content + "," + prefix) } } //ObjectA隐式转换的作用域 object ObjectAWrapper { implicit val DEFAULT_OBJECT_A_STRING = "ObjectA" } object ImplicitArgument { def main(args : Array[String]) { ObjectA.print("ABC")( "DEF") import ObjectAWrapper._ //Error: not enough argument if this line doesn't exist //为String类型的参数隐式的提供DEFAULT_OBJECT_A_STRING值 ObjectA.print("ABC") ObjectA.print("ABC")( "XYZ") } }
隐式参数的应用
如下代码出错:
class A[T] { def min(a: T, b: T) { if (a < b) a else b //泛型类T没有定义<方法 } } object ImplicitArgument { def main(args : Array[String]) { val a = new A[Int](); a.min(10,11) } }
package spark.examples.scala class A[T] { //这里相当于为T指定约束,即T必须能够隐式转换到Ordered //T能够隐式转换到Ordered,那么对类型T的变量使用<操作时,将隐式地将T转换为Ordered类型的变量,然后调用Ordered类型的<方法 //T隐式转换到Ordered,需要预先定义 def min(a: T, b: T) (implicit order: T=>Ordered[T]) = { if (a < b) a else b } } object ImplicitArgument2 { def main(args : Array[String]) { val a = new A[Int](); println(a.min(10,11)) //Scala已经实现了Int到Ordered的隐式转换,否则3 < 4做不了 class B {} /** 报错的原因是No implicit view available from B => Ordered[B].即B没有定义到Ordered的隐式转换,所以报错 val b = new A[B]() // b.min(new B(), new B()) **/ } }
三、隐式类
增强一个类型
隐式类约束
- 隐式类必须有一个带一个参数的主构造函数
- 必须定义在另一个class/object/trait里面(不能独立定义)
- 隐式类构造器只能带一个不是implicit修饰的参数
- 作用域中不能有与隐式类类型相同的成员变量,函数以及object名称
package spark.examples.scala class B { def add(x: Int, y: Int) = { x + y } } object ImplicitClassContext { //隐式类,可以为一个类型(参数的类型)提供方法 //为主构造函数指定的类型进行增强 implicit class RichB(arg: B) { def multiply(x: Int, y: Int) = { x * y } } } object ImplicitClass { def main(args: Array[String]) { import ImplicitClassContext._ val b = new B(); println(b.multiply(3, 4)) } }
相关推荐
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
【课程大纲】 第1讲-Spark的前世今生 共12页 第2讲-课程介绍、特色与价值 共13页 第3讲-Scala编程详解:基础语法 共8页 ...第20讲-Scala编程详解:隐式转换与隐式参数 共9页 第21讲-Scala编程详解:Actor入门 共8页
赠送jar包:scala-xml_2.11-1.0.4.jar; 赠送原API文档:scala-xml_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.4-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.4.pom; 包含翻译后的API...
赠送jar包:scala-xml_2.12-1.0.6.jar; 赠送原API文档:scala-xml_2.12-1.0.6-javadoc.jar; 赠送源代码:scala-xml_2.12-1.0.6-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.12-1.0.6.pom; 包含翻译后的API...
很大篇幅都放在,使用scala实现scala默认库文件的API中,通过对简单的函数式编程逻辑的介绍和实践,主要是实践,建立起来一个比较明晰的scala思维模式,或者叫函数式编程的思维模式。 2 无副作用的函数式编程,同时...
Scala隐式转换和隐式参数.md
赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 赠送Maven依赖信息...
赠送jar包:scala-parser-combinators_2.11-1.0.4.jar; 赠送原API文档:scala-parser-combinators_2.11-1.0.4-javadoc.jar; 赠送源代码:scala-parser-combinators_2.11-1.0.4-sources.jar; 包含翻译后的API...
赠送jar包:scala-java8-compat_2.11-0.7.0.jar; 赠送原API文档:scala-java8-compat_2.11-0.7.0-javadoc.jar; 赠送源代码:scala-java8-compat_2.11-0.7.0-sources.jar; 赠送Maven依赖信息文件:scala-java8-...
Learn Scala is split into four parts: a tour of Scala, a comparison between Java and Scala, Scala-specific features and functional programming idioms, and finally a discussion about adopting Scala in...
赠送jar包:scala-xml_2.11-1.0.5.jar; 赠送原API文档:scala-xml_2.11-1.0.5-javadoc.jar; 赠送源代码:scala-xml_2.11-1.0.5-sources.jar; 赠送Maven依赖信息文件:scala-xml_2.11-1.0.5.pom; 包含翻译后的API...
在IntelliJ中调试Scala隐式 本文档概述了用于静态分析IntelliJ中的Scala隐式方法的几种补充方法。 JetBrains提供了的,但不包括有关分析富集对象的说明。 注意:这些快捷方式适用于OSX。 查看隐式转换 突出显示...
scala是一种基于JVM的面向对象的函数编程,scala编程相对于java而言代码整洁、开发效率更高。 其中scala优点主要有: 1:面向对象,可以定义class,通过new调用实例对象使用。 2:兼容java,在scala中可以直接调用...