最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

scala 基础 4

[复制链接]
跳转到指定楼层
楼主
发表于 2018-3-16 13:26:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

隐式转换

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

隐式转换函数

以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"namename,ageage")的返回值  */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"namename,ageage"}

泛型:
泛型就是不确定的类型,可以在类或方法不确实传入类型时使用,可以提高代码的灵活性和复用性
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好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-4-24 15:47

Powered by BI168大数据社区

© 2012-2014 168大数据

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