scala学习手记35 - 隐式类型转换
先来看一下下面的内容:
2 days “ago”
5 days “from_now”
如上的内容具体应该是什么呢?不过怎么看也不像是代码。不过既然是在学代码,拿不是代码的东西出来做什么!
非要强说是代码的话,那么执行起来肯定是要报错的——因为scala的Int和RichInt,以及Integer中都没有days这样的方法:
如果说不是代码的话,那么scala中的to或until本来看起来也不像代码:
2 to 6
2 until 7
现在剩下的就是怎么为整型值添加上days方法。这就涉及到如何扩展整型类了。我自己想了好久也没想到妥帖的法子。
教材中提供了一个方案,就是采用隐式类型转换。
隐式类型转换可以帮助我们扩展语言,创建“专用于特定应用和领域”的词汇或语法,也可以帮助我们创建属于自己的领域专用语言。
关于隐式类型转换,教材上就是这么说的。从这句话里可以看到隐式类型转换为我们留下了巨大的扩展空间。
先来看看如何解决眼前的事情。要为整型值添加RichInt方法需要先创建一个DateHelper类:
class DateHelper(number: Int) { def days(when: String): Date = {
val date = Calendar.getInstance()
when match {
case "ago" => date.add(Calendar.DAY_OF_MONTH, -number)
case "from_now" => date.add(Calendar.DAY_OF_MONTH, number)
case _ => date
}
date.getTime()
}
}
在DateHelper类中提供了我们需要的days方法。我们要做的就是将给定的数字转换为DateHelper对象。类继承是不行的,强制类型转换也是不行的,可以考虑在需要的时候将整型值转换为DateHelper实例。简单的把方法标记为implicit,只要这个方法在当前范围内存在,scala就会自动调用这个方法:
implicit def convertInt2DateHelper(number: Int) = new DateHelper(number)
把上面的代码同DateHelper类一起运行就可以自动将整数值转换为DateHelper实例,然后就可以调用days()方法了。
来看一下完整的代码:
import java.util._ class DateHelper(number: Int) { def days(when: String): Date = {
val date = Calendar.getInstance()
when match {
case "ago" => date.add(Calendar.DAY_OF_MONTH, -number)
case "from_now" => date.add(Calendar.DAY_OF_MONTH, number)
case _ => date
}
date.getTime()
}
} implicit def convertInt2DateHelper(number: Int) = new DateHelper(number) val ago = "ago"
val from_now = "from_now" val past = 2 days ago
val appointment = 5 days from_now println(past)
println(appointment)
看一下执行结果:
接下来可以对代码稍作调整。我们并不想在每次需要转换时都去写隐式转换器。把这个转换器放到一个单独的单例对象里,可以获得更好的重用性,也更加易用。可以把转换器挪到DateHelper的伴生对象里:
import java.util._ class DateHelper(number: Int) {
def days(when: String): Date = {
val date = Calendar.getInstance()
when match {
case DateHelper.ago => date.add(Calendar.DAY_OF_MONTH, -number)
case DateHelper.from_now => date.add(Calendar.DAY_OF_MONTH, number)
case _ => date
} date.getTime()
}
} object DateHelper {
val ago = "ago"
val from_now = "from_now" implicit def convertInt2DateHelper(number: Int) = new DateHelper(number)
}
导入DateHelper时,Scala会自动的找到转换器。这是因为Scala会在当前范围和导入的范围内进行转换。
在Predef对象里,Scala已经定义了一些隐式转换,Scala会默认导入它们。这样的话,比如说,当我们写1 to 3时,Scala就会隐式的将1从Int转换为其富封装器RichInt,然后,调用to()方法。Scala一次至多应用一个隐式转换。
在当前范围内,如果发现通过类型转换有助于操作、方法调用或类型转换的成功完成,就会进行转换。
######################
scala学习手记35 - 隐式类型转换的更多相关文章
- Scala学习二十一——隐式转换和隐式参数
一.本章要点 隐式转换用于类型之间的转换 必须引入隐式转换,并确保它们可以以单个标识符的形式出现在当前作用域 隐式参数列表会要求指定类型的对象.它们可以从当前作用域中以单个标识符定义的隐式对象的获取, ...
- Scala 学习笔记之隐式参数和隐式转换并用
隐式转换条件: 1. 当表达式类型与预期的类型不同时 2.当对象访问一个不存在的成员时 3.当对象调用某个方法,而该方法的参数声明与传入参数不相匹时. 隐式转换搜索范围: 1. 位于源火目标类型伴生对 ...
- JavaScript学习总结(二、隐式类型转换、eval())
一.(避免)隐式类型转换 console.log(false == 0); //logs true; console.log(false === 0); //logs false; conso ...
- Scala进阶之路-Scala高级语法之隐式(implicit)详解
Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...
- C++的隐式类型转换
C++是一种复杂的语言,其中有许多“好玩”的特性,学习C++的过程就像在海边捡一颗颗石头,只要坚持不懈,也许一颗颗小石头也能建起你自己小小的城堡. 废话完后,讲讲自己捡到的石头:隐式类型转换 学习出处 ...
- 深入js隐式类型转换
前言 相信刚开始了解js的时候,都会遇到 2 =='2',但是 1+'2' == '1'+'2'为false的情况,这时候应该会是一脸懵逼的状态,不得不感慨js弱类型的灵活让人发指,隐式类型转换就是这 ...
- javascript的隐式类型转换
首先简单了解js的typeof,会返回六种类型 即 number string boolen function object undefined 也就是六种基本数据类型 显示类型转换大概有以下几种: ...
- js条件判断时隐式类型转换
Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...
- dynamic_cast 和 static_cast 隐式类型转换的区别
首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion ...
随机推荐
- 160628、利用Oracle rownum让表排序字段值连续
利用Oracle rownum让表排序字段值连续 1.需求说明 表(eval_index)中有字段如下: 表字段 描述 说明 ID 主键 GROUP_ID 分组编号 SORT_NUM 排序序号 按照分 ...
- 制作简易app个人总结
1.每次修改app.js或者其他路由js文件,都必须重启node app.js,否则修改不起作用!!! 2.<link rel="stylesheet" href=" ...
- convention over configuration 约定优于配置 按约定编程 约定大于配置 PEP 20 -- The Zen of Python
为什么说 Java 程序员必须掌握 Spring Boot ?_知识库_博客园 https://kb.cnblogs.com/page/606682/ 为什么说 Java 程序员必须掌握 Spring ...
- 高性能网站服务器的架设优化-Nginx优化
一:对于高性能网站 ,请求量大,如何支撑?思路 在网站架构设计中,大家一定对 LNMP (Linux Nginx Mysql Php) 不陌生.LNMP 确实是一个非常优秀的架构,秉承着自由,开放,高 ...
- travelsal all files in a dir using recursion shell
#!/bin/bash function getdir(){ ` do dir_or_file=$"/"$element if [ -d $dir_or_file ] then g ...
- 【转】如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
网上看到关于微信官方的跨平台跨业务的终端基础组件Mars的介绍文章,转载这这里.源代码: https://github.com/Tencent/mars作者:男人链接:https://zhuanlan ...
- Andrew Ng机器学习编程作业:Logistic Regression
编程作业文件: machine-learning-ex2 1. Logistic Regression (逻辑回归) 有之前学生的数据,建立逻辑回归模型预测,根据两次考试结果预测一个学生是否有资格被大 ...
- Sql server用QQ邮箱发送邮件
一.配置数据库邮件 https://jingyan.baidu.com/article/3ea51489a135f752e71bba5b.html
- 001-ant design pro安装、目录结构、项目加载启动【原始、以及idea开发】
一.概述 1.1.脚手架概念 编程领域中的“脚手架(Scaffolding)”指的是能够快速搭建项目“骨架”的一类工具.例如大多数的React项目都有src,public,webpack配置文件等等, ...
- use html5 video tag with MSE for h264 live streaming
本编博客记录桌面虚拟化移动端预研. 完整demo: https://github.com/MarkRepo/wfs.js 常见的直播方案有RTMP RTSP HLS 等等, 由于这些流都需要先传输到服 ...