Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一个人添加是不现实的,因此很多很多时候需要我们自己动手。掌握implicit的用法是阅读Spark源码的基础,也是学习Scala其它的开源框架的关键,implicit可分为隐式参数,隐式转换类型以及隐式类三种类型。
一.Scala中的隐士参数
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaImplicit object ScalaImplicit { /**
* 定义一个隐式值,编译器在查找隐式值的时候,不能出现歧义,也就是说,编译器在编译代码的时候,不能找到
* 两个类型一致的隐式值,不然编译器是会编译不通过的!
*/
implicit val default:Int = 500 /**
* @param Name : 此处我们将Name设置为隐士的参数
*/
def sayHello(implicit Name:String = "YinZhengJie") = {
println(s"I'm ${Name},I love Beijing !")
} /**
* @param x : 柯里化函数(Currying)的第一个参数
* @param y :柯里化函数(Currying)的第二个参数,其类型为一个隐式的参数哟
* @return : 返回值类型为Int
*/
def add(x:Int)(implicit y:Int):Int={
x + y
} /**
* 方法的参数如果有多个隐式参数的话,只需要使用一个implicit关键字即可,隐式参数列表必须放在方法的参数列表后面
*/
def sum(a:Int)(implicit b:Int,c:Int):Int={
a + b + c
} def main(args: Array[String]): Unit = { sayHello("yinzhengjie") /**
* sayHello方法参数是隐式参数,如果你没有给sayHello传递参数的话,编译器在编译的时候会自动从当前的上下文中
* 找一个隐式值(符合参数类型的隐式值),如果有则使用,如果没有就使用sayHello方法参数的默认值,指的注意的是,当一
* 各类中出现了多个implicit变量时,貌似默认值也不好使了!当前的类我就定了2个implicit变量就是一个很好的例子!
*/
// sayHello implicit val msg:String = "尹正杰"
sayHello /**
* 在调用柯里化函数(Currying)的时候,我们仅仅出入了第一个参数,第二个参数默认就是类中的成员变量用implicit修饰的default的值。
*/
val res = add(20)
println(s"res =====》 ${res}") /**
* 本来需要传入3个参数的,但是我们就传了一个,其他两个参数就会默认使用类中的成员变量用implicit修饰的default的值。
*/
val res2 = sum(10)
println(s"res2 =====》 ${res2}")
}
} /*
以上代码输出结果如下:
I'm yinzhengjie,I love Beijing !
I'm 尹正杰,I love Beijing !
res =====》 520
res2 =====》 1010
*/
二.Scala中的隐式类型转换
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaImplicit object ScalaImplicit { /**
* 使用关键字implicit定义一个隐式方法。
*/
implicit def doubleToInt(double: Double):Int = {
println("====== 调用了方法:doubleToInt ======")
double.toInt
}
/**
* 使用关键字implicit定义一个隐式函数。
*/
implicit val doubleToInt2 = (double:Double) => {
println("====== 调用了函数:doubleToInt2 ======")
double.toInt
} def main(args: Array[String]): Unit = { /**
* year是一个Int类型的变量,但是赋值的确实一个浮点型数字,此刻编译器会在当前上下文中找一个
* 隐式转换,找一个能把浮点型变成Int类型的隐式转换的函数或者方法,如果有函数实现了这个功能就优先
* 调用函数的功能,若没有函数实现该功能就回去找是否有方法实现了该功能!如果函数或者方法都没有实现
* 该功能编译器是会报错的!
*/
val year:Int = 2018.7
println(s"year的结果是: ${year}")
}
} /*
以上代码输出结果如下:
====== 调用了函数:doubleToInt2 ======
year的结果是: 2018
*/
三.Scala中的隐式类
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaImplicit import java.io.File import scala.io.Source object ScalaImplicit {
/**
* 定义隐式类,只能在静态对象(使用Object修饰)中使用
*/
implicit class FileRead(file:File){
def myRead() = Source.fromFile(file).mkString
} def main(args: Array[String]): Unit = {
val file = new File("D:\\10.Java\\IDE\\yhinzhengjieData\\Scala\\1.txt")
val lineCounts = file.myRead()
println(s"file文件对象里面的内容如下:\n${lineCounts}")
}
} /*
以上代码输出结果如下:
file文件对象里面的内容如下:
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
hello wolrd
*/
四.小试牛刀(封装File对象,新增lineCount方法,用来统计文件的行数,要求使用隐式方法)
/*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie.scalaImplicit import java.io.{BufferedReader, File, FileReader} /**
* 自定义一个RichFile类,封装File类
*/
class RichFile(file:File){
/**
* 定义方法返回文件的记录行数
*/
def linesCount():Int={
val fileReader = new FileReader(file)
val bufferReader = new BufferedReader(fileReader) var sum = 0
try {
var line = bufferReader.readLine()
while (line != null) {
sum += 1
line = bufferReader.readLine()
}
} catch {
case _: Exception => sum
} finally {
fileReader.close()
bufferReader.close()
}
sum
}
} object ScalaImplicit {
/**
* 定义一个隐式方法,将File类型转换成RichFile类型。
*/
implicit def fileToRichFile(file: File) = {
new RichFile(file)
} def main(args: Array[String]): Unit = {
val file = new File("D:\\10.Java\\IDE\\yhinzhengjieData\\Scala\\1.txt") val lineCounts = file.linesCount()
println(s"file文件对象里面的行数是:${lineCounts}")
}
} /*
以上代码输出结果如下:
file文件对象里面的行数是:18
*/
Scala进阶之路-Scala高级语法之隐式(implicit)详解的更多相关文章
- Scala进阶之路-Scala中的高级类型
Scala进阶之路-Scala中的高级类型 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.类型(Type)与类(Class)的区别 在Java里,一直到jdk1.5之前,我们说 ...
- Scala进阶之路-Scala的基本语法
Scala进阶之路-Scala的基本语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数式编程初体验Spark-Shell之WordCount var arr=Array( ...
- Scala进阶之路-Scala中的Ordered--Ordering
Scala进阶之路-Scala中的Ordered--Ordering 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 说道对象的比较,在Java中大家最熟悉不过的就是实现类本身实 ...
- Scala进阶之路-Scala中的泛型介绍
Scala进阶之路-Scala中的泛型介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 通俗的讲,比如需要定义一个函数,函数的参数可以接受任意类型.我们不可能一一列举所有的参数类 ...
- Scala进阶之路-Scala特征类与unapply反向抽取
Scala进阶之路-Scala特征类与unapply反向抽取 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala特征类分析 1>.Unit 答:用于定义返回值类型, ...
- Scala进阶之路-Scala函数篇详解
Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...
- Scala进阶之路-Scala中的枚举用法案例展示
Scala进阶之路-Scala中的枚举用法案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的枚举值和Java中的枚举值有点差别,不过使用起来也都差大同小异,我这 ...
- Scala进阶之路-高级数据类型之集合的使用
Scala进阶之路-高级数据类型之集合的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala 的集合有三大类:序列 Seq.集 Set.映射 Map,所有的集合都扩展自 ...
- Scala进阶之路-高级数据类型之数组的使用
Scala进阶之路-高级数据类型之数组的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的初始化方式 1>.长度不可变数组Array 注意:顾名思义,长度不可变数 ...
随机推荐
- 20135337——linux第四次实践:字符集总结与分析
ASCII & GB2312 & UTF-8 ASCII 主要用于显示现代英语和其他西欧语言.它是现今最通用的单字节编码系统,并等同于国际标准ISO 646: 7位(bits)表示一个 ...
- [2017BUAA软工]第零次博客作业
第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 当年高考前在专业这件事上纠结了好久,因为我对于大学各个专业具体学什么都不甚了解,于是就迟迟没有明确的目 ...
- ubuntu编译安装php7遇到的问题及解决方案
configure: error: Cannot find OpenSSL's <evp.h> 这个可以在configure的时候,指定openssl的路径,查看openssl的安装路径: ...
- PAT L2-012 关于堆的判断
https://pintia.cn/problem-sets/994805046380707840/problems/994805064676261888 将一系列给定数字顺序插入一个初始为空的小顶堆 ...
- [CNBETA]动图告诉你 光速到底有多慢?
https://www.cnbeta.com/articles/tech/811381.htm 我们知道,30万公里每秒的光速是宇宙内目前已知的最高速度,至少现有人类理论体系下它是不可跨越的.30万公 ...
- python 协程库gevent学习--gevent数据结构及实战(四)
一不留神已经到第四部分了,这一部分继续总结数据结构和常用的gevent类,废话不多说继续. 1.Timeout错误类 晚上在调试调用第三方接口的时候,发现有些接口耗时非常多,觉得应该有个超时接口来限制 ...
- flask+mako+peewee(上)
其实关于什么用flask搭建一个后台博客啥的跟着官方文档做一遍就行了.感觉啥都有我这里就不赘述了只是记录一个笔记,因为稍微有几个地方有点坑. 目标:做了一个简易页面给电商的同事用来添加商品 首先是安装 ...
- codeforces1045B
CF1045B 自己瞎鸡巴yy了一下,可知若一个数X不能被表示出来,那么X所有的表示方法都在A集合中,如a1,a2,a3······an-1,an-2中若a1+ai不能被表示出来,那么如果a1到ai是 ...
- Cenos7 添加service,开机启动
本地有一个 data-service.jar 1. 编写启动脚本 data-service-start [root@iz2ze0fq2isg8vphkpos5sz shell]# more data ...
- [代码]--c#-实现局域网聊天
服务器端: using System; using System.Collections.Generic; using System.Linq; using System.Net; using Sys ...