版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
19.隐式转换与隐式参数一、隐式定义的含义及规则二、隐式地转换到期望类型三、隐式地转换接收端四、隐式类五、含有隐式参数的主构造方法六、上下文界定七、多个匹配的隐式定义2目
录一、隐式定义的含义及规则
3一、隐式定义的含义及规则1.1隐式定义的含义程序员事先写好的定义,允许编译器隐式地插入这些定义来解决类型错误。这部分定义通常对使用者不可见,并且由编译器自动调用,故而得名“隐式定义”。隐式转换属于隐式定义的一种。4一、隐式定义的含义及规则标记规则。只有用关键字“implicit”标记的定义才能被编译器隐式使用,任何函数、变量或单例对象都可以被标记。作用域规则。Scala编译器只会考虑在当前作用域内的隐式定义,否则,所有隐式定义都是全局可见的将会使得程序异常复杂甚至出错。
1.2隐式定义的规则5每次一个规则。编译器只会插入一个隐式定义,不会出现“convert1(convert2(x))+y”这种嵌套的形式,但是可以让隐式定义包含隐式参数来绕开这个限制。显式优先原则。如果显式定义能通过类型检查,就不必进行隐式转换。因此,总是可以把隐式定义变成显式的,这样代码变长但是歧义变少。用显式还是隐式,需要取舍。
一、隐式定义的含义及规则1.2隐式定义的规则6二、隐式地转换到期望类型
7二、隐式地转换到期望类型把一个浮点数赋值给整数变量会报错。2.1不使用隐式转换scala>vali:Int=1.5
<console>:11:error:typemismatch;
found:Double(1.5)
required:Int
vali:Int=1.5scala的编译器对于类型检查比较严格。8二、隐式地转换到期望类型使用隐式转换可以正确地将数据转换到期望的类型。2.2使用隐式转换scala>importscala.language.implicitConversions
importscala.language.implicitConversions
scala>implicitdefdoubleToInt(x:Double)=x.toInt
doubleToInt:(x:Double)Int
scala>vali:Int=1.5
i:Int=1定义一个double转Int的隐式转换函数。9三、隐式地转换接收端
10三、隐式地转换接收端scala>classMyInt(vali:Int)
definedclassMyInt
scala>1.i
<console>:14:error:valueiisnotamemberofInt
1.i
^scala>implicitdefintToMy(x:Int)=newMyInt(x)
intToMy:(x:Int)MyInt
scala>1.i
res1:Int=1因为标准值类Int没有叫“i”的字段而报错定义一个隐式转换函数,会将Int对象转换成MyInt对象,使i的访问合法。“1.i”被编译器隐式地展开成了“intToMy(1).i”11四、隐式类
12四、隐式类4.1基本介绍使用关键字“implicit”声明。编译器会在隐式类的相同层次下自动生成一个与类名相同的隐式转换函数,该转换接收一个与隐式类的主构造方法相同的参数,并用这个参数构造一个隐式类的实例对象来返回。4.2注意事项隐式类不能是caseclass,并且主构造方法有且仅有一个参数。隐式类只能被定义在“类”、“单例对象”或“特质”里,不能单独出现在顶层。13四、隐式类4.3定义一个构造长方形的隐式类自动生成的caseclassRectangle(width:Int,height:Int)
objectRec{
implicitclassRectangleMaker(width:Int){
defx(height:Int)=Rectangle(width,height)
}
//implicitdefRectangleMaker(width:Int)=newRectangleMaker(width)
}14四、隐式类4.4使用隐式类scala>importRec.RectangleMaker
importRec.RectangleMaker
scala>1x10
res0:Rectangle=Rectangle(1,10)scala>1x10
<console>:12:error:valuexisnotamemberofInt
1x10
^Int类并不存在方法“x”隐式转换函数RectangleMaker可以把Int对象转换成一个RectangleMaker类的对象15五、隐式参数
16五、隐式参数在函数的最后一个参数列表中使用关键字“implicit”将该参数列表中的参数都声明为隐式的,这样整个参数列表的参数都是隐式参数。如:5.1声明方式注意,即使括号里有多个参数,也只需要开头写一个“implicit”。而且每个参数都是隐式的,不存在部分隐式部分显式。defgreet(name:String)(implicitprompt:PreferredPrompt, drink:PreferredDrink)隐式参数包括隐式变量、隐式对象、隐式函数。最后一个参数列表17五、隐式参数5.2举例classPreferredPrompt(valpreference:String)
classPreferredDrink(valpreference:String)
objectGreeter{
defgreet(name:String)(implicitprompt:PreferredPrompt,
drink:PreferredDrink)={
println("Welcome,"+name+".Thesystemisready.")
print("Butwhileyouwork,")
println("whynotenjoyacupof"+drink.preference+"?")
println(prompt.preference)
}
}
objectJoesPrefs{
implicitvalprompt=newPreferredPrompt("Yes,master>")
implicitvaldrink=newPreferredDrink("tea")
}隐式参数列表隐式对象18五、隐式参数缺省隐式参数列表,编译器会尝试自动插入相应的隐式定义。5.3使用方式一scala>importJoesPrefs._
importJoesPrefs._
scala>Greeter.greet("Joe")
Welcome,Joe.Thesystemisready.
Butwhile
youwork,whynotenjoyacupoftea?
Yes,master>scala>Greeter.greet("Joe")
<console>:12:error:couldnotfindimplicitvalueforparameterprompt:PreferredPrompt
Greeter.greet("Joe")
^缺省隐式参数列表19五、隐式参数也可以显式给出参数,但是要么全部缺省,要么全部显式给出,不能只写一部分。5.4使用方式二scala>Greeter.greet("Joe")(prompt,drink)
Welcome,Joe.Thesystemisready.
Butwhile
youwork,whynotenjoyacupoftea?
Yes,master>
scala>Greeter.greet("Joe")(prompt)
<console>:15:error:notenoughargumentsformethodgreet:(implicitprompt:PreferredPrompt,implicitdrink:PreferredDrink)Unit.
Unspecifiedvalueparameterdrink.
Greeter.greet("Joe")(prompt)显式提供参数部分缺省20六、含有隐式参数的主构造方法
21六、含有隐式参数的主构造方法6.1声明方式classA(implicit
valx:Int)不仅是普通的函数可以有隐式参数,类的主构造方法也可以包含隐式参数。辅助构造方法是不允许出现隐式参数的。22六、含有隐式参数的主构造方法如果类A仅有一个参数列表,且是隐式的,那么A的实际定义形式是“A()(implicit参数)”。若调用主构造方法时显式给出隐式参数,就必须写出这个空括号。6.2使用细节一scala>classA(implicitvalx:Int)
definedclassA
scala>vala=newA(1)
<console>:12:error:noargumentsallowedfornullaryconstructorA:()(implicitx:Int)A
vala=newA(1)
^scala>vala=newA()(1)
a:A=A@7cf8f45a23六、含有隐式参数的主构造方法若隐式参数由编译器自动插入,则空括号可有可无。6.3使用细节二scala>implicitvalORZ=233
ORZ:Int=233
scala>valb=newA
b:A=A@7d977a20
scala>b.x
res0:Int=233scala>valc=newA()
c:A=A@de0c402
scala>c.x
res1:Int=23324七、上下文界定
25七、上下文界定假设现在需要编写一个方法寻找“最大”的列表元素,并且具体行为会根据某个隐式Ordering[T]对象发生改变,那么可能定义如下:7.1maxList[T]函数的常规写法defmaxList[T](elements:List[T])(implicitordering:Ordering[T]):T=
elementsmatch{
caseList()=>thrownewIllegalArgumentException("emptylist!")
caseList(x)=>x
casex::rest=>
valmaxRest=maxList(rest)(ordering)//参数ordering被显式传递
if(ordering.gt(x,maxRest))x//参数ordering被显式使用
elsemaxRest
}26七、上下文界定隐式导入的Predef对象里定义了下面这样一个函数:defimplicitly[T](implicitt:T)=t在缺省参数的情况下,编译器会在当前作用域下自动寻找一个T类型的隐式对象传递给参数t,然后把这个对象返回。例如,implicitly[ORZ]就会把当前作用域下的隐式ORZ对象返回。7.2implicitly[T]函数27七、上下文界定7.3maxList[T]函数使用implicitly[T]的简洁写法defmaxList[T](elements:List[T])(implicitordering:Ordering[T]):T=
elementsmatch{
caseList()=>thrownewIllegalArgumentException("emptylist!")
caseList(x)=>x
casex::rest=>
valmaxRest=maxList(rest)
if(implicitly[Ordering[T]].gt(x,maxRest))x
elsemaxRest
}28七、上下文界定[T:Ordering]7.4上下文界定语法7.5上下文界定的两层含义defmaxList[T:Ordering](elements:List[T]):TdefmaxList[T](elements:List[T])(implicitordering:Ordering[T]):T引入一个类型参数T添加一个类型为Ordering[T]的隐式参数29七、上下文界定7.6maxList[T]函数使用[T:Ordering]的简洁写法defmaxList[T:Ordering](elements:List[T]):T=
elementsmatch{
caseList()=>thrownewIllegalArgumentException("emptylist!")
caseList(x)=>x
casex::rest=>
valmaxRest=maxList(rest)
if(implicitly[Ordering[T]].gt(x,maxRest))x
elsemaxRest
}上下文界定30八、多个匹配的隐式定义
31八、多个匹配的隐式定义8.1模棱两可的隐式定义scala>classA(implicitvalx:Int)
definedclassA
scala>implicitvalz=10
z:Int=10
scala>implicitvalzz=100
zz:Int=100
scala>vala=newA()
<console>:14:error:ambiguousimplicitvalues:
bothvaluezoftype=>Int
andvaluezzoftype=>Int
matchexpectedtypeInt
vala=newA()
^两个隐式变量都符合作为类A主构造函数的参数的条件32八、多个匹配的隐式定义8.2更具体的定义---条件1该定义的类型是更模糊的定义的子类型。scala>classA(implicitvalx:Int)
definedclassA
scala>implicitvalz=10
z:Int=10
scala>implicitvalzz:Any=100
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年高职(化妆品技术)化妆品配方基础试题及答案
- 2025年大学人类学(人类学基础)期末试题
- 2025年中职(会展服务与管理)会展现场服务阶段测试题及答案
- 2025年大学动画设计(动画制作基础)试题及答案
- 2025年中职农业机械使用与维护(农机操作基础)试题及答案
- 2025年高职航空油料管理和应用(油料管理技术)试题及答案
- 2025年大学(护理学)护理信息学试题及答案
- 2025年大学(车辆工程)汽车电子技术试题及答案
- 2026年食品营养与检验教育(食品检验教育)考题及答案
- 2026年成都农业科技职业学院单招综合素质笔试备考题库带答案解析
- 邢台课件教学课件
- 医防融合视角下家庭医生签约慢病管理策略
- 2025年新能源市场开发年度总结与战略展望
- 中职历史期末考试及答案
- 从指南看慢性乙型病毒性肝炎的防治策略
- 江苏省扬州市江都区2025-2026学年八年级第一学期第二次月考语文答案
- 互联网企业绩效考核方案与实施细则
- 2026年辽宁装备制造职业技术学院单招职业技能测试题库带答案详解
- 贵州兴义电力发展有限公司2026年校园招聘备考题库及1套完整答案详解
- 2026年及未来5年市场数据中国电磁兼容测试市场竞争格局及投资战略规划报告
- 公安内务条令课件
评论
0/150
提交评论