scala隐式转换

来源:互联网 发布:淘宝自动浏览收藏软件 编辑:程序博客网 时间:2024/05/22 07:57
package test.zhuanhuanimport java.io.Fileimport scala.io.Source// implict def形式的隐式转换object ImplicitDefDemo {    object MyImplicitTypeConversion {        implicit def strToInt(str: String) = str.toInt    }    def main(args: Array[String]) {        //compile error!        //val max = math.max("1", 2);        import MyImplicitTypeConversion.strToInt        val max = math.max("10", 2);        println(max)    }}//隐式类 形式的隐式转换/**  * 隐式类有如下几个限制  *     它们必须在另一个类//对象中定义。  *     他们可能只在构造函数中使用一个非隐式参数。  *     在范围内,可能没有任何方法、成员或对象与隐式类相同  *     这意味着一个隐式类不能是一个case  */object ImplicitDefDemo1 {    object MyImplicitTypeConversion {        implicit def strToInt(str: String) = str.toInt    }    def main(args: Array[String]) {        //compile error!        //val max = math.max("1", 2);        import MyImplicitTypeConversion.strToInt        val max = math.max("1", 2);        println(max)        //隐士视图        def g(arg:String) = println("Hello:  "+ arg)        implicit def int2String(arg:Int):String = arg.toString        g(8888)    }}/**  * ①隐式值可以用于给方法提供参数  * ②隐式视图是指把一种类型自动转换成另外一种类型,进而使用另外一种类型中的属性和方法,从而满足表达式的要求  * 隐士视图一般定义成  *     implicat def myFunctionName(argName:OriginlType):ViewType  *  *     作用:如果在隐式作用域里存在这个定义,它会隐式地把原始类型的值转换为增强之后的类型的值  */object App{    def main(args: Array[String]): Unit = {        //隐士值        implicit val str ="Scala"        def fun(implicit arg:String) = println("Hello:"+"\t"+arg)        fun(str)    //打印 Hello:    Scala        fun         //打印 Hello:    Scala    }}//@案例1----------------------------------------------------------------------------------------/**  * 通过伴生类与伴生对象机制,编译器将会自动导入隐式转换, 而无需用户手动导入隐式转换。  */class S1{    def fun(str:String) = println(str)}class S2object S2{    //隐式视图      隐式视图是指把一种类型自动转换成另外一种类型,进而使用另外一种类型中的属性和方法,从而满足表达式的要求.    implicit def s2toS1(arg:S2)  = new S1()}object Abc{    def main(args: Array[String]): Unit = {        val s2 = new S2()        s2.fun("Spark")  //输出Spark  自动使用自己伴生对象中的隐式视图    }}//@案例2 -----------------------------------------------------------------------------------class RichFile(var file:File){    def read():String = Source.fromFile(file).mkString}class F1(path:String) extends File(path)object F1{    //隐士转换类在半生对象中 转换成RichFile对象    implicit def filetoRichFile(arg:File) = new RichFile(arg)}object Test{    def main(args: Array[String]): Unit = {        val s1:F1 = new F1("C:/USERS/OS/DESKTOP/NEW.TXT")        val text1:String = F1.filetoRichFile(s1).read() //调用方法转换        val text2 = s1.read()   //使用隐式转换        println(text1)        println(text2)    }}//-------------------------------------------------------------------------------------------/**  * Scala中的隐式转换相关操作规则  *     ①在Scala当中,要想使用隐式转换,必须标记为implicit关键字,implict关键字可以用来修饰参数(隐式值与隐式参数)、函数(隐式视图)、类(隐式类)、对象(隐式对象).  *     ②隐式转换在整个作用域中,必须是单一的标识符,进而避免隐式冲突.  *     ③在隐式转换的作用域查找中,如果当前作用域没有隐式转换,编译器就会自动到相应源或目标类型的伴生对象中查找隐式转换。  *     Scala中的隐式值、隐式类、隐式对象常放在单例对象object.  */object Test2{    def main(args: Array[String]): Unit = {        //隐士值        implicit val str = "Spark"        def fun(implicit arg:String) = println(arg)        fun        //隐士对象        trait T1{def g():Unit}        implicit object T2 extends T1{            override def g(): Unit = println("Hello Spark")        }        def fun2(arg1:String)(implicit arg2:T1) = println("隐式对象")        fun2("Scala")(T2)        fun2("Java")        //隐式对象在这里作为隐式值    }}//-------------------------------------------------------/**  * Scala中的隐式参数  *    ①在Scala当中,所谓隐式参数就是在函数或方法中的参数前面加上implicit修饰符,这样的参数叫做隐式参数.  *    ②在Scala当中,若在函数的参数前面含有implicit修饰符,编译器就会自动寻找相应的隐式值作为默认值(缺省值)进行传递  */object T1{    implicit val str ="Hadoop"}object Test3{    def main(args: Array[String]): Unit = {        //arg2作为一个隐式参数        def fun(arg1:String)(implicit arg2:String) = println(arg1 + " : " + arg2)        fun("Scala")("Spark")        import T1.str   //导入隐式值 如果注释掉此行(could not file implicat value for parameter arg2:String)        fun("Hadoop")    }}//---------------------------------------------------------------------------------------------/**  * Scala中的隐式类  *     Scala中的隐式类就是在普通类的前面加上一个implicit关键字,并修改相应的主构造器,主构造器的参数类型一般是转换之前的类的类型,最后在隐式作用域内导入即可。Scala中的隐式类是对类功能增强的一种形式.  *     Scala中的隐式视图是在转换之前的类的伴生对象中做文章,Scala中的隐式类是在增强的类中做文章,因为前者不用手动导入,所以Scala中的隐式类相比于隐式视图用的较少.  *     ③单例对象中可以构建静态的属性和方法,还可以构建静态的类,若想使用单例对象中的静态类,import导入即可。  */object T2{    //隐式类    implicit class RichFile(file:File){        def read():String = Source.fromFile(file.getPath).mkString    }}object Test4{    //scala中隐式类是对增强后的类中做文章,并且构造器的参数类型一般是转换之前的类型    def main(args: Array[String]): Unit = {        val file = new File("c:/users/os/desktop/new.txt")        import T2.RichFile        val text:String = file.read()        println(text)    }}//-----------------------------------------------------------/**  * Scala中的隐式对象  *     Scala中的隐式对象就是在object对象前面加上implicit修饰符,隐式对象在某种程度上而言可以作为隐式值进行使用.  *     ②在Scala当中,标注类型的时候可以直接用类和特质的名字来引用其类型,而要引用对象的类型,需要用对象的type成员来引用其类型,而不能直接用object的名字来引用其类型,主要是为了区别伴生对象和伴生类.  */object Test5{    def main(args: Array[String]): Unit = {        trait S1{            def fun():Unit        }        implicit object S2 extends S1{            def fun(): Unit = println("Spark")        }        def g(arg1:String)(implicit arg2:S1) = println("隐式对象")        g("Scala")(new S1{def fun()=println("Spark")})        //隐式对象在这里充当隐式值来shiy        g("scala")    }}//----------------------------------------------/**  * Scala中的两种隐式类型约束(结合Scala中的类型系统)  *     Scala支持两种特殊的类型约束操作符,它们其实不是真正的类型约束而是隐式查找,这两种操作符就是上下文界定和视图界定。这些操作符允许你定义一个隐式参数列表来作为泛型类型的类型约束。  *         在隐式转换定义必须可被查找到但不需要直接访问的情况下,这种语法可以让你少打点字。隐式类型约束的两种类型分别是视图界定(涉及到了隐式视图)和上下文界定(隐式值)  *  *     ①视图界定用来要求一个可用的隐式视图(内部机制)来将一种类型自动转换成另外一种类型。隐式视图的定义如下:  *         def foo[A <% B](x:A) = x  *         含义:foo方法定义了一个约束 A <% B,意思是参数x的类型为A,并且在调用的地方必须存在相应的隐式转换 A=>B,可以用下面的写法表达出同样的意思:  *         def foo[A](x:A)(implicat m:A =>B) = x  *         这个foo方法也可以用一个不带类型约束的类型参数来定义。有两个参数:一个接受一个A类型的参数,第二个接受一个隐式转换函数。  *         尽管第二种形式要打更多字,但是他给隐式转换函数打了个用户自定义的标签  *  *  *  *     ②上下文界定用来要求一个可用的隐式值存在,且必须存在。上下文界定如下:  *         def foo[A : B](x:A) = x  *         foo方法定义了约束A:B,这个约束的含义是参数x的类型为A,并且调用foo方法时必须有一个可用的隐式值B[A]存在,上下文界定可以重新这样写:  *         def foo[A](x:A)(implicat arg:B[A]) = x  *         这个foo方法定义了两个参数,其隐式参数接受一个B[A]类型的值。尽管第二种形式要打更多字,但是他给隐式值打了个用户自定义的标签。  */object Test6{    def main(args: Array[String]): Unit = {        //视图界定 :隐式的需要一个隐式视图:T=>Ordered        def bigger1[T <% Ordered[T]](first:T,second:T):T={            if(first > second) first else second            //if(first .>(second)) first else second        }        val aa = bigger1(10,20)        println(aa)        //视图界定的第二种方式,明确的需要一个隐式视图:T>Ordered        def bigger2[T](first:T,second:T)(implicit f:T=>Ordered[T])={            if(f(first).>(second))first else second        }        val bb = bigger2(10,20)        println(bb)    }}object Test7{    def main(args: Array[String]): Unit = {        //上下文界定, 隐式的需要一个隐式值:Ordering[T]        def bigger1[T:Ordering](first:T,second:T):T={            if(Ordering[T].compare(first,second)>0) first else second        }        val aa = bigger1(10,20)        println(aa)        //上下文界定的第二种方式,明确的需要一个隐式值:Ording[T]        def bigger2[T](first:T,second:T)(implicit m:Ordering[T]):T={            if(m.compare(first,second)>0) first else second        }        val bb = bigger2(10,20)        println(bb)    }}class Bigger[T:Ordering](val first:T,val second:T){    def bigger(implicit m:Ordering[T]) = if(m.compare(first,second)>0) first else second}//----------------------------------------------------------------------------/**  * Predef类中的implicitly方法的用法介绍以及Ordering类型转化为Oredered类型的方式  *     Predef类中的implicitly方法可以获取参数实际运行时具体的数值  *         def implicitly[T](implicit e:T) = e  *     Ordered的伴生对象中含有很多内容:其中一个就是将Ordering数据类型隐式的转化为Oredered类型:  *         object Ordered{  *             implicit def orderingToOrdered[T](x:T)(implicit ord:Ordering[T]):Ordered[T] = new Ordered[T]{  *                 def compare(that:T):Int = ord.compare(x,that)  *             }  *         }  */object Test9{    def main(args: Array[String]): Unit = {        val str:String = implicitly("Spark")        val i :Int  = implicitly(10)        println(str)        println(i)        println("----------")        val aa = new Bigger[Int](10,20)        println(aa.bigger)    }}object Test10{    def main(args: Array[String]): Unit = {        val aa = new Bigger1[Int](10,20)        println(aa.bigger)    }}class Bigger1[T:Ordering](var first:T,var second:T){    import scala.Ordered.orderingToOrdered    def bigger()={        if(orderingToOrdered[T](first)(Ordering[T]).compare(second)>0) first else second    }}
原创粉丝点击