在Scala中implicit 转换有三种:
1.隐式参数与隐式值
package com.demo
object ImplicitPram {
//在作用域内,只能指定一个同类型的隐式参数。
implicit val a = 100
/**
* 在参数前加上implicit 关键字,表示a,b都是隐式参数,在调用时,可以显示的调用如
* test_Param(1,2),亦可test_Param方式调用。
* @param a
* @param b
*/
def test_Param(implicit a:Int,b:Int): Unit ={
println(s"a=$a,b=$b")
}
/**
* 当部分参数为implicit参数时,需使用柯里化方式定义,且隐式参数在后面,调用时,可以只使用
* 一个显示的参数,也可以同时使用隐式和非隐式参数。
* @param name
* @param a
*/
def test_P2(name:String)(implicit a:Int): Unit ={
println(s"name=$name,a=$a")
}
def main(args: Array[String]): Unit = {
// test_Param(1,2) 指明参数的调用
test_Param //使用隐式参数,此时参数a,b的值均为100
// test_P2("hello") //调用时,不使用隐式参数
test_P2("hello")(10) //同时传入显示参数,和隐式参数。
}
}
2.隐式函数
package com.demo
/**
* 定义一个鸟类,有一个方法fly
* @param xname
*/
class Bird(xname:String){
val name = xname
def fly(): Unit ={
println(s"$name can fly ...")
}
}
/**
* 定义一个猪类
* @param xname
*/
class Pig(xname:String){
val name = xname
}
object ImplicitFun {
/**
* 定义一个函数,使用implicit修饰,同时参数传入猪的一个对象,返回值为鸟类
*
* 请注意:隐式函数只与参数类型,和返回类型有关,与函数名称无关,故在作用域内不能存在
* 参数类型相同,返回类型不同的隐式转换函数。
* @param p
* @return
*/
implicit def pigToBird(p:Pig):Bird={
new Bird(p.name)
}
def main(args: Array[String]): Unit = {
new Pig("pery").fly()
/*
创建一个猪的对象,调用fly 方法,此时,猪的对象会先寻找自己的fly 方法,若自己没有,若发现其他类有fly 方法,则会在作用域内寻找
是否有隐式函数将猪的类型转换为鸟的类型,若有,就可以调用鸟的fly 方法。
*/
}
}
3.隐式类
package com.demo
/**
* 定义一个猪对象
* @param xname
*/
class Pig(xname:String){
val name = xname
}
object ImplicitClass_demo {
/**
* 定义了一个隐式类,当一个对象调用它本身没有的方法和变量或常量时,若隐式类中有,
* 就会调用隐式类的的变量或常量和方法。
* 隐式类必须定义在类中,包对象,或伴生对象中,同时,构造器只能有一个参数,就是隐式调用的类型。同一包中,类中,
* 或伴生对象中,不能出现构造器参数类型相同的隐式类。
* @param pig
*/
implicit class bird(pig:Pig){
val ss = "blue sky"
val name = pig.name
def canFly(): Unit ={
println(s"$name can fly ...")
}
}
def main(args: Array[String]): Unit = {
val pig = new Pig("pery")
pig.canFly() //猪对象调用canfly 方法,本身没有,实际调用的时bird 的方法
println(pig.ss) //猪对象没有ss的常量,实际上调用的时bird 的ss常量。
}
}