清楚了什么时候会发生隐式转换,现在再来看一下什么情况下不会发生隐式转换。
1)如果转换存在二义性,则不会发生隐式转换,见例8-11。
【例8-11】存在二义性时不会发生隐式转换示例。
例8-11第8行、第10行代码定义了两个隐式转换函数,分别是person2Superman、per⁃son2Superman2,这两个隐式转换函数输入类型都是Person类,输出类型都为SuperMan类,因此第19行代码p.fly()编译时会出错,编译器给出“Note that implicit conversions are not applicable because they are ambiguous…”提示。
2)隐式转换不会嵌套进行,示例代码见例8-12。
【例8-12】隐式转换不会嵌套进行示例。(www.daowen.com)
例8-12第1~3行代码定义了SuperMan类,第4~6行代码定义了另外一个SuperSuper⁃Man类,类中定义了一个fly2方法,其调用的是SuperMan类中的fly方法,第10行代码定义了一个Person到SuperMan的隐式转换函数,第12行代码又定义了一个SuperMan到Su⁃perSuperMan的隐式转换函数,第16行代码p.fly2()期望的是Person类能够隐式转换成Su⁃perMan,然后再进一步隐式转换成SuperSuperMan,最终调用SuperSuperMan的fly2方法,但事实上这是行不通的,Scala语言不允许嵌套隐式转换。之所以做这样的限制是有原因的,隐式转换如果可以嵌套,会使代码的行为难以控制,隐式转换可能无限地进行下去,严重降低编译和执行效率,甚至造成代码无法执行。
需要注意的是,隐式转换不会嵌套进行指的是从源类型到目标类型的隐式转换不会多次进行,也即源类型到目标类型的转换只会进行一次,这并不意味着程序中不会发生多次隐式转换,具体代码如例8-13所示。
【例8-13】多次隐式转换的示例。
代码执行结果如下:
例8-13第14~17行代码,定义了一个隐式转换函数implicit def B2C(b:ClassB),该函数将ClassB隐式转换为ClassC,第18~21行代码定义了一个隐式转换函数implicit def D2C(d:ClassD),该函数将ClassD隐式转换成ClassC,编译器遇到第25行代码时,发现classD对象调用的方法是printC方法,但ClassD类中并没有定义printC方法,因此尝试进行隐式转换,自动调用D2C隐式转换函数完成ClassD到ClassC的转换(第一次隐式转换)。在执行printC方法时,发现传入的参数类型为ClassB,而def printC(c:ClassC)方法接受的参数是ClassC,类型不匹配,所以编译器又尝试进行隐式转换,自动调用B2C隐式转换函数,将ClassB转换成ClassC(第二次隐式转换)。在完成这两次隐式转换后,程序得以顺利执行。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。