scala隐式转换

来源:互联网 发布:浪潮软件股票走势 编辑:程序博客网 时间:2024/05/18 01:36

1、 隐式转换函数
隐式转换的深层机制是隐式转换函数(implicit conversion method),隐式函数前加上implicit
如将Double转换成Int

implicit def Double2Int(x:Double)=x.toIntval x:Int=1.55   //x=1

隐式函数与函数的标签有关,即于输入输出类型有关,与函数名称无关
隐式转换函数可以快速的扩展类的功能。

class superclass{def fly()=println(“Superman flying”)}class personobject implicitFunction extends App{implicit def person2superPerson(p:person)=new superclassval p=new personp.fly()    //Superman flying}

2、 隐式类与隐式对象
隐式类是在class前加上implicit关键字

class personobject implicitFunction extends App{implicit class superclassp:person){def fly()=println(“Superman flying”)}val p=new personp.fly()    //Superman flying}

隐式类的构造函数是隐式函数

隐式参数、隐式值
隐式参数只能在函数列表中出现一次,implicit作用域是整个函数参数,科里化函数的implicit只能放在最后一个参数中
匿名函数不能使用隐式参数
带有隐式参数的函数不能使用其部分应用函数

def sum(implicit x:Int,y:Int)=x+yimplicit val x:Int=5sum   //编译器自动在相应作用域中查找对应的隐式值//实际调用sum(5+5)

3、 类型证明中的隐式转换
类型证明,也称类型约束,作用是进行类型测试,
T=:=U
T<:

object typeConstraint extends App{def test[T](name:T)(implicit ev:T<:<java.io.Serializable)={name}//String类型实现了Serializable接口,属于Serializable的子类println(test(“张三“))println(test(165))//error!Int类型没有实现Serializable接口,不属于Serializable的子类}

<:<和<:的·差别:
<:类型不匹配时,使用类型推断采用父类进行匹配
<:<严格匹配,不会采用父类进行匹配,隐式转换在此不管用。

4、 上下文界定、视图界定中的隐式转换
Ordering混入java中的Comparator接口,外部比较器
Ordered混入Comparable接口,内部比较器

java中Comparator接口使用实例

     public class Person{private String name;public String getName(){return name;}public void setName(String name){tis.name=name;}public Person(String name){this.name=name;}}public class PersonComparator implements Comparator<Person>{@overridepublic int compara(Person o1,Person o2){if(o1.getName().equalsIgnoreCase(o2.getName())){return 1;}else{return -1;}}public static void main(String[] args){PersonComparator pc=new PersonComparator();Person p1=new Person(“张三”);Person p2=new Person(“张三2“);if(pc.compara(p1,p2)>0)System.out.pintln(p1.getName());elseSystem.out.println(p2.getName());}}

Comparable接口在java中的运用。

public class Person implements Comparator<Person>{private String name;public String getName(){return name;}public void setName(String name){tis.name=name;}public Person(String name){this.name=name;}@overridepublic int comparator(Person o){if(name.equalsIgnoreCase(o.getName())){return 1;}else{return -1;}}}public class PersonComparable{public static void main(String[] args){Person p1=new Person(“张三”);Person p2=new Person(“张三2“);if(p1.compara(p2)>0)System.out.pintln(p1.getName());elseSystem.out.println(p2.getName());}}

所以ordered是内部比较器

case class Student(val name:String) extends Ordered{override def compara(that:Student):Int={if(this.name==that.name)1else-1}}class pairComparable[T<:Ordered[T]](val first:T,val second:T){def smaller()={if(first<second)firstelsesecond}}object OrderedViewBound extends App{val p=new pairComparable(Student(“张三“),Student(“张三2”))println(p.smaller)}

界图转换
不仅仅是指定类层次的类,还可以是隐式转换后的类

\\利用<%符号对泛型S进行限定,即S可以是在类继承层次结构中实现了Comparable的类\\也可以是能够进行隐式转换得到的类case class Student[T,S<%Comparable[S]](var name;String,var height;Int)object viewBoundextends App{val s=Student(“john”,”170”)val s1=Student(“john”,170)println(s2)//Student(“john”,170)}

上下文界定类型参数为T:M,其中M是一个泛型,要求存在一个M[T]类型的隐式值。

//类型参数可以有一个形式为T:M的上下文界定,其中M是另一个泛型类型。它要求作用域中存在一个类型为M[T]的隐式值class Pair_Implicits[T: Ordering](val first: T, val second: T) { //Ordering[T]def bigger(implicit ordered: Ordering[T]) =if (ordered.compare(first, second) > 0) first else second}class Pair_Implicitly[T: Ordering](val first: T, val second: T) {def bigger = if (implicitly[Ordering[T]].compare(first, second) > 0)first else second}class Pair_Implicitly_Odereded[T: Ordering](val first: T, val second: T) {def bigger = {import Ordered._if (first > second) first else second}}object Context_Bounds_Internals {def main(args: Array[String]): Unit = {println(new Pair_Implicits(7, 9).bigger)println(new Pair_Implicitly(7, 9).bigger)println(new Pair_Implicitly_Odereded(7, 9).bigger)}}

发生隐式转换的条件:
1) 隐式转换函数必须在有效的作用域内才能生效
2) 当方法中的参数类型与实际类型不一致时,编译器尝试进行隐式转换,
3) 当调用类中不存在的对象或方法时,会自动将对象进行隐式转换。
不发生隐式转换的条件:
1) 转换存在二义性
2) 隐式转换不会嵌套进行