scala高级内容(二) - Implicit
一. Implicit关键字
隐士转换
(1)隐士转换函数:用implicit修饰的,只有一个参数的函数。他会被自动执行,来把一个值转换成另一个class RichFile(val f:File){
def read = Source.fromFile(f).mkString
}
implicit def file2richFile(f:File) = new RichFile(f) //隐士转换函数
val result: String = new File("/home/lj/chrome.sh").read
println(result)
(2)隐士转换函数可以卸载伴生对象中,需要的时候import进来
(3)当一个隐士函数没有被scala调用,可以显示的调用函数,有可能出现错误提示
【注】:
(a) 隐士转换优先转换参数,后去尝试转换调用方法的对象
(b) 隐士转换不能同时使用多个转换。eg:convert1(convert2(a))
(c) 二义性错误:如果2个隐士转换函数都能用到参数转换,则编译器报错
函数的隐士参数
(1)函数参数列表中的某个参数,用implicit生命,则这个函数成为包含隐士参数的函数。
(2)调用隐士参数的函数,可以显式传入参数,也可以省略不传,scala从上下文查找隐士对象,自动传进函数中class Delimeters(val left:String,val right:String){}
def quote(value:String)(implicit delimeters: Delimeters)=println(delimeters.left+value+delimeters.right)
quote("spark")(new Delimeters("<",">")) //显示调用
implicit val deli = new Delimeters("<<",">>")
quote("hadoop") // 自动推断
隐士转换function作为函数的隐士参数
有时一个函数的参数类型为泛型T,不能确定参数有哪些方法可被调用。因此,函数的参数类表中,使用隐士转换函数作为参数,从而确定参数列表有哪些方法能被调用//Predef中含有大量的T->Ordered[T]的隐士转换函数
def getBigger[T](a:T,b:T)(implicit ord : T=>Ordered[T])={ //ord是一个隐士转换函数,用implicit修饰后,成为隐士参数。scala要根据前文查找是否有这样一个函数
if(a>b) a else b
}
println(getBigger(2,3))
上下文界定
上下文界定是对隐士参数的简化语法,这个隐士参数的类型要是M[T],简化掉函数参数中的隐士参数。那函数内部如何使用原来的隐士参数呢,2种方法:定义内部函数,把省略的隐士参数在内部函数中还原出来;第二个是用implicity还原这个变量object Test extends App{
// 隐士参数
def max[T](a:T,b:T)(implicit cp:Ordering[T])={
if (cp.compare(a,b)>0) a else b
}
println(max(1,3)) // 上下文界定精简隐士参数,表示的语义还是要有Ordering[T]类型的隐士参数
def max2[T:Ordering](a:T,b:T)={
// 1.内部函数使用隐士参数
def innermax(implicit op:Ordering[T]) = {
if (op.compare(a,b)>0) a else b
}
innermax
}
println(max2(3,6)) // 2. implicify还原隐士参数
def max3[T:Ordering](a:T,b:T)={
val op = implicitly[Ordering[T]]
if (op.compare(a,b)>0) a else b
}
println(max3(23,1))
}
类型证明参数
(1)格式:implicit 类型证明参数名:泛型1 <:<,<%<,<=< 泛型2
(2)作用:当函数右两个泛型时,类型证明参数可以证明一个泛型是另一个泛型的(子类型,视图类型,相等类型)//firstlast方法,会在调用时确定2个类型。C:函数的参数类型。A是iterable里的类型(List中的元素类型)。
def firstLast[A,C](it:C)(implicit demonstrate: C<:<Iterable[A]) = { // 如果没有类型证明参数demonstrate,定义函数时,无法确定C是什么类型。也就无法调用参数的方法
(it.head,it.last)
}
println(firstLast(List(1,2,5))) // scala推断出泛型[Int,List[Int]]
println(firstLast[Int,List[Int]](List(1,2,5))) // 手动指定泛型[Int,List[Int]]
二. @implicitNotFound注解
@implicitNotFound
@implicitNotFound注解在无法找到隐士参数,隐士转换,或推出的泛型不匹配时给出提示信息@implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.")
sealed abstract class <:<[-From, +To] extends (From => To) with Serializable
Manifest和typetag
// Manifest和typetag存储被擦出泛型信息
class Foo{class Bar}
def m(f: Foo)(b: f.Bar)(implicit ev: TypeTag[f.Bar]) = ev // TypeTag解决Manifest的依赖路径问题
val f1 = new Foo;val b1 = new f1.Bar
val f2 = new Foo;val b2 = new f2.Bar
val ev1 = m(f1)(b1)
val ev2 = m(f2)(b2)
println(ev1==ev2) // false。 使用manifest的结果是true
scala高级内容(二) - Implicit的更多相关文章
- scala高级内容(一) Case Class
一. 操作符 自定义操作符 操作付默认左结合调用.除了以:结尾的操作符是右结合调用 object OperaterTest extends App{ val a: myInt = new myInt( ...
- Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...
- 一个完整的Installshield安装程序实例—艾泽拉斯之海洋女神出品(四) --高级设置二
原文:一个完整的Installshield安装程序实例-艾泽拉斯之海洋女神出品(四) --高级设置二 上一篇:一个完整的安装程序实例—艾泽拉斯之海洋女神出品(三) --高级设置一4. 根据用户选择的组 ...
- Lucene的查询及高级内容
Lucene查询 基本查询: @Test public void baseQuery() throws Exception { //1. 创建查询的核心对象 FSDirectory d = FSDir ...
- ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪
ASP.NET MVC深入浅出(被替换) 一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...
- 02.Scala高级特性:第6节 高阶函数;第7节 隐式转换和隐式参数
Scala高级特性 1. 课程目标 1.1. 目标一:深入理解高阶函数 1.2. 目标二:深入理解隐式转换 2. 高阶函数 2.1. 概念 Scala混合了面向对象和函数式的特 ...
- Stm32高级定时器(二)
Stm32高级定时器(二) 1 主从模式:主?从? 谈论主从,可知至少有两个以上的触发或者驱动信号,stm32内部有多个定时器,可以相互之间驱动或者控制. 主模式:定时器使能只受驱动时钟控制或者输出控 ...
- Solidity高级理论(二):Gas
solidity高级理论(二):Gas 关键字:Gas.结构体.节省小技巧 Gas是什么 在Solidity中,用户想要执行DApp都需要支付一定量的Gas,Gas可以用以太币购买,所以,用户每次使用 ...
- Scala学习(二)——高级特性
apply() 方法 apply方法是Scala提供的一个语法糖 类名+括号,调用对象的apply方法 对象名+括号,调用类的apply方法 对apply方法的简单测试:(其中,带 new -- cl ...
随机推荐
- boot/bootsect.S
!! SYS_SIZE is the number of clicks (16 bytes) to be loaded.! 0x7F00 is 0x7F000 bytes = 508kB, more ...
- HDU 4705 Y 树形枚举
树形枚举--搜索 题目描述: 给你一棵树,要在一条简单路径上选3个不同的点构成一个集合,问能构成多少个不同的集合. 解法: 枚举所有结点,假设某个结点有n棵子树,每棵子树的结点个数分别为s1,s2,` ...
- html5的改进与沿革
HTML5提供了一些新的元素和属性,例如<nav>(网站导航块)和<footer>.这种标签将有利于搜索引擎的索引整理,同时更好的帮助小屏幕装置和视障人士使用,除此之外,还为其 ...
- FZU 1343 WERTYU --- 水题
FZU 1343 题目大意:手放在键盘上时,稍不注意就会往右错一位.这样Q就会输入成W,输入J就会变成K 给定一串大写敲错后输入,输出正确的输入(输入保证合法,如输入中不会出现Q,A,Z): 解题思路 ...
- 增量更新项目时的备份MyBak
在增量更新项目时,做好备份十分重要,这里提供一个方法备份java Web所更新的文件. 把更新包放在指定目录,配好如下webappFolder.updateFolder以及bakeupFolder的路 ...
- hdu5443(2015长春赛区网络赛1007)暴力
题意:给了一个数列,有多个询问,每个询问求某个区间内的最大值 数列长度 1000,询问个数 1000,静态,并不需要RMQ这些,直接暴力 n2 查找每个询问区间取最大值就行了. #include< ...
- 跟上节奏 大数据时代十大必备IT技能(转)
新的想法诞生新的技术,从而造出许多新词,云计算.大数据.BYOD.社交媒体……在互联网时代,各种新词层出不穷,让人应接不暇.这些新的技术,这些新兴应用和对应的IT发展趋势,使得IT人必须了解甚至掌握最 ...
- [poj 3261]Milk Patterns
后缀数组搞一下就可以了喵~ 其实这道题的第一个想法是 SAM ,建完后缀自动机后拓扑排序跑一遍统计下每个子串的出现次数就 O(N) 就妥妥过掉了 后缀树也是 O(N) 的,统计一下每个节点对应的子树中 ...
- note: declarations in dependent base ‘std::basic_ios<char>’ are not found by unqualified lookup
错误信息如题所示. 修改前: template< typename _CharT, typename _Traits = std::char_traits<_CharT> > ...
- Choosing proper innodb_log_file_size
If you’re doing significant amount of writes to Innodb tables decent size of innodb_log_file_size is ...