先来看一下下面的内容:

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 - 隐式类型转换的更多相关文章

  1. Scala学习二十一——隐式转换和隐式参数

    一.本章要点 隐式转换用于类型之间的转换 必须引入隐式转换,并确保它们可以以单个标识符的形式出现在当前作用域 隐式参数列表会要求指定类型的对象.它们可以从当前作用域中以单个标识符定义的隐式对象的获取, ...

  2. Scala 学习笔记之隐式参数和隐式转换并用

    隐式转换条件: 1. 当表达式类型与预期的类型不同时 2.当对象访问一个不存在的成员时 3.当对象调用某个方法,而该方法的参数声明与传入参数不相匹时. 隐式转换搜索范围: 1. 位于源火目标类型伴生对 ...

  3. JavaScript学习总结(二、隐式类型转换、eval())

    一.(避免)隐式类型转换 console.log(false == 0);   //logs true; console.log(false === 0);   //logs false; conso ...

  4. Scala进阶之路-Scala高级语法之隐式(implicit)详解

    Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...

  5. C++的隐式类型转换

    C++是一种复杂的语言,其中有许多“好玩”的特性,学习C++的过程就像在海边捡一颗颗石头,只要坚持不懈,也许一颗颗小石头也能建起你自己小小的城堡. 废话完后,讲讲自己捡到的石头:隐式类型转换 学习出处 ...

  6. 深入js隐式类型转换

    前言 相信刚开始了解js的时候,都会遇到 2 =='2',但是 1+'2' == '1'+'2'为false的情况,这时候应该会是一脸懵逼的状态,不得不感慨js弱类型的灵活让人发指,隐式类型转换就是这 ...

  7. javascript的隐式类型转换

    首先简单了解js的typeof,会返回六种类型 即 number string boolen function object undefined 也就是六种基本数据类型 显示类型转换大概有以下几种: ...

  8. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  9. dynamic_cast 和 static_cast 隐式类型转换的区别

    首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1部分. 隐式类型转换 又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion ...

随机推荐

  1. 160628、利用Oracle rownum让表排序字段值连续

    利用Oracle rownum让表排序字段值连续 1.需求说明 表(eval_index)中有字段如下: 表字段 描述 说明 ID 主键 GROUP_ID 分组编号 SORT_NUM 排序序号 按照分 ...

  2. 制作简易app个人总结

    1.每次修改app.js或者其他路由js文件,都必须重启node app.js,否则修改不起作用!!! 2.<link rel="stylesheet" href=" ...

  3. convention over configuration 约定优于配置 按约定编程 约定大于配置 PEP 20 -- The Zen of Python

    为什么说 Java 程序员必须掌握 Spring Boot ?_知识库_博客园 https://kb.cnblogs.com/page/606682/ 为什么说 Java 程序员必须掌握 Spring ...

  4. 高性能网站服务器的架设优化-Nginx优化

    一:对于高性能网站 ,请求量大,如何支撑?思路 在网站架构设计中,大家一定对 LNMP (Linux Nginx Mysql Php) 不陌生.LNMP 确实是一个非常优秀的架构,秉承着自由,开放,高 ...

  5. 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 ...

  6. 【转】如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

    网上看到关于微信官方的跨平台跨业务的终端基础组件Mars的介绍文章,转载这这里.源代码: https://github.com/Tencent/mars作者:男人链接:https://zhuanlan ...

  7. Andrew Ng机器学习编程作业:Logistic Regression

    编程作业文件: machine-learning-ex2 1. Logistic Regression (逻辑回归) 有之前学生的数据,建立逻辑回归模型预测,根据两次考试结果预测一个学生是否有资格被大 ...

  8. Sql server用QQ邮箱发送邮件

    一.配置数据库邮件 https://jingyan.baidu.com/article/3ea51489a135f752e71bba5b.html

  9. 001-ant design pro安装、目录结构、项目加载启动【原始、以及idea开发】

    一.概述 1.1.脚手架概念 编程领域中的“脚手架(Scaffolding)”指的是能够快速搭建项目“骨架”的一类工具.例如大多数的React项目都有src,public,webpack配置文件等等, ...

  10. use html5 video tag with MSE for h264 live streaming

    本编博客记录桌面虚拟化移动端预研. 完整demo: https://github.com/MarkRepo/wfs.js 常见的直播方案有RTMP RTSP HLS 等等, 由于这些流都需要先传输到服 ...