隐式函数
隐式函数就是类似于scala在背地里默默帮我们处理一些既定的方法。
1.隐式转换函数
隐式转换函数值得是那种以implicit关键字声明的带有单个参数的函数。正如他的名称所表达的,这样的函数将被自动应用,将值从一种类型转换为另一种类型。
//定义了一个隐式函数 默认将Double转换为Int
scala> implicit def double2Int(x:Double)=x.toInt
scala> val x:Int=3.5
x:Int=3
2.引入隐式转换的方式
- 隐式转换可以定义在目标文件当中
implicit def double2Int(x:Double)=x.toInt var x:Int=3.5
- 隐式转换集中放置在某个保重,在使用的时候直接将该包引入即可(在引入包的时候最后面应该是._结尾)
package MenthodTool{
object ImplicitCover{
implicit def double2Int(x:Double)=x.toInt
implicit def df(x:Double)=x.toString
}
}
object test1 extends App{
import MenthodTool.ImplicitCover._
val x:Int=3.5
println(x)
}
3.隐式转换规则(使用)
- 当表达式的类型与实预期的类型不一致时。
scala> val x:Int=3.5 //这个会报错,因为期望的值为Int,输入却为double
//所以为了解决这个问题引入隐式转换,再次执行x:Int=3.5就不会报错了
scala> implicit def Double2Int(x:Double)=x.toInt
scala>val x:Int=3.5
x:Int=3
- 当调用类中不存在的成员和调用某个方法时,该方法的参数声明与传入参数不匹配时,会自动将对象进行隐式转换。
4.隐式转换规则(不使用)
- 如果代码能够在不使用隐式转换的前提下通过编译,则不会使用隐式转换。 例如 ab 能够编译的还,那么编译器不会尝试aconvert(b)
- 编译器不会尝试同时执行多个转换,例如 convert1(convert2(a))*b
- 存在二义性的转换时错误的。例如a*convert(b)和convert(a)*b都是合法的话,编译器将会报错。
5.隐式参数
函数或方法可以带有一个标记为implicit的关键字。在这种情况下,编译器将会去查找相关类或是引入包中的缺省值,提供给函数或方法。
//未加隐式参数=============
class OutPutFormat(var first:String,val second:String)
class student(var name:String){
def formatStudent(outPutFormat: OutPutFormat)={outPutFormat.first+" "+name+" "+outPutFormat.second}
}
object ImplicitParamters{
def main(args: Array[String]): Unit = {
val out=new OutPutFormat("<",">")
println( new student("John").formatStudent(out))
}
}
//增加隐式参数的话,能够增加默认的格式
class OutPutFormat1( var first:String,val second:String)
class Student1(var name:String){
//增加implicit关键字,可以不带参数使用
def formatStudent()(implicit out:OutPutFormat1)={out.first+" "+name+" "+out.second}
}
object ImplicitParamters2{
//增加implicit关键字,对于方法表示有了默认的值
implicit val df=new OutPutFormat1("<",">")
def main(args: Array[String]): Unit = {
println( new Student1("John").formatStudent())
}
}
注意: 定义的隐式值要唯一,不能再同一个域中存在多个隐式值,这样会造成编译器找到多个隐式值,导致调用报错。