搜索
查看: 1288|: 0

scala 基础 4

[复制链接]

42

主题

0

回帖

204

积分

中级会员

积分
204
发表于 2018-3-16 13:38:02 | 显示全部楼层 |阅读模式

隐式转换

作用:能够丰富现有类库的功能,对类的方法进行增强

隐式转换函数

以implicit关键字声明并带有单个参数的函数

比如1 to 10其实是调用的1.to(10)这个方法
但是在Int类中并没有to这个方法

int 的to方法实际上是调用RichInt里的intWrapper方法,最终调用的是RichInt里的to方法
intWrapper就是以implicit关键字声明并带有单个参数的函数,intWrapper就是一个隐式转换函数
predef这个类就是预定义的predefine的简写


在shell中用:implicit -v来查看,默认有多少个隐式转换函数
在2.11.8中有69个隐式转换,scala升级比较快所以其它版本可能不同

隐式转换函数其实用到了装饰模式
装饰模式对应的是门面模式

隐式转换练习:
给代表文件地址的字符串增加一个可以读文件的功能

import scala.io.Sourceclass ImplicitFunctionDemo(val path:String) {def read():String = {Source.fromFile(path).mkString}}object ImplicitFunctionDemo{def main(args: Array[String): Unit = {val path = "C:\\Users\\Leo.He\\Desktop\\抽取项目描述.txt"val content: String = new ImplicitFunctionDemo(path).read()println(content)}}

这是一个显示的调用并不是一个隐式的调用,这是我们平时开发过程中常用的方法

隐式转换函数的实现方法
1.首先在MyPredef写一个String的隐式转换函数

object MyPredef {implicit def pathStringToImplicitFunction(path:String) = new ImplicitFunctionDemo(path)}

2.然后修改刚才的类为隐式转换的调用方式,在使用隐式转换中String类型的path变量就有了read方法,这个read实现上是ImplicitFunctionDemo的read。
这个转换过程是由MyPredef里的隐式转换函数完成的

import scala.io.Sourceclass ImplicitFunctionDemo(val path:String) {def read():String = {Source.fromFile(path).mkString}}object ImplicitFunctionDemo{def main(args: Array[String): Unit = {val path = "C:\\Users\\Leo.He\\Desktop\\抽取项目描述.txt"val content: String = new ImplicitFunctionDemo(path).read()println(content)import MyPredef.pathStringToImplicitFunctionval content1 = path.read()println(content1)}}

隐式转换与柯里化的使用
shell中柯里化与隐式转换使用的例子

/**  * 这里用到了隐式转换、隐式值、柯里化(隐式参数)、内部类、泛型、特质、比较的方法、重写toString方法  * 首先import OrderingDemo.OrderStudent  * OrderStudent是Ordering[HainiuStudent]的子类  * 所以demo.comp() 柯里化方法(def comp()(implicit ord:Ordering[HainiuStudent])) 第二个参数会匹配到OrderStudent  * 所以ord的值传入的是OrderStudent  * ord.gt(v1,v2)调用的是OrderStudent的gt方法也就是ordering的gt方法(def gt(x: T, y: T): Boolean = compare(x, y) > 0)  * ordering的gt方法中调用的是compare,但OrderStudent是ordering的子类实现,所以调用的是orderStudent的compare方法  * 由OrderStudent的compare方法返回会的正负值决定了返回true还是false,(Boolean = compare(x, y) > 0)  大于0是true小于0是false  * demo.comp()(def comp()(implicit ord:Ordering[T]))方法返回比较之后的对象  * println(student)打印了对象重写的toString方法(override def toString: String = s"name:$name,age:$age")的返回值  */object OrderingDemo {implicit object OrderStudent extends Ordering[HainiuStudent{override def compare(x: HainiuStudent, y: HainiuStudent): Int = if(x.age > y.age) 1 else -1}}class CompareDemo[T:Ordering(val v1:T,val v2:T){def comp()(implicit ord:Ordering[T) = if(ord.gt(v1,v2)) v1 else v2}object CompareDemo{def main(args: Array[String): Unit = {import OrderingDemo.OrderStudentval s1 = new HainiuStudent("牛1",24)val s2 = new HainiuStudent("牛2",23)val demo = new CompareDemo[HainiuStudent(s1,s2)//    val demo = new CompareDemo(s1,s2)   //简写的方式val student: HainiuStudent = demo.comp()println(student)}}class HainiuStudent(val name:String,val age:Int){override def toString: String = s"name:$name,age:$age"}

泛型:
泛型就是不确定的类型,可以在类或方法不确实传入类型时使用,可以提高代码的灵活性和复用性
scala中泛型的用法和java中差不多,但是会有一些自己独特的语法

比如说ordering中泛型的一些特殊符号


这个叫ViewBound


这个叫UpperBound

泛型:
[B <: A] UpperBound 上界,B类型的父类是A类型
[B >: A] LowerBound 下界,B类型的子类是A类型
[B <% A] ViewBound B类型转换成A类型,需要一个隐式转换函数
[B : A] ContextBound 需要转换成A[B]类型,需要一个隐式转换的类型
[-A] 逆变,作为参数类型,T是A的子类
[+B] 协变,作为返回类型,T是B的父类

UpperBound

class UpperBoundDemo[T <: Comparable[T {def choose(a:T,b:T):T = {if(a.compareTo(b) > 0) a else b}}object UpperBoundDemo{def main(args: Array[String): Unit = {val u = new UpperBoundDemo[HaniuEngineerval h1 = new HaniuEngineer("牛大",20)val h2 = new HaniuEngineer("牛二",22)println(u.choose(h1,h2))}}class HaniuEngineer(val name:String,val age:Int) extends Comparable[HaniuEngineer{override def compareTo(o: HaniuEngineer): Int = {this.age - o.age    //SCALA中访问本类的属性也可以用this}override def toString: String = {s"${name}我年纪大"}}

ViewBound

class ViewBoundDemo[T <% Ordered[T {def choose(work1:T,work2:T):T={if(work1 > work2) work1 else work2}}object ViewBoundDemo{def main(args: Array[String): Unit = {import MyPredef.selectWorkval demo = new ViewBoundDemo[HainiuWorkval work1 = new HainiuWork("金融",20000,10)val work2 = new HainiuWork("互联网",20000,6)print(demo.choose(work1,work2))}}class HainiuWork(val company:String,val money:Int,val holiday:Int){override def toString: String = {s"go to $company,happy holiday $holiday"}}

隐式转换函数实现


版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海牛部落-青牛,http://hainiubl.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

大数据中国微信

QQ   

版权所有: Discuz! © 2001-2013 大数据.

GMT+8, 2024-11-15 18:38 , Processed in 0.065242 second(s), 24 queries .

快速回复 返回顶部 返回列表