scala成长之路(5)问题记录
还是在看scala sdk源码的时候,有很多问题要考自己慢慢摸索,这里做个记录。
一. 隐式转换的作用域?
隐式转换需要三个因素
1. 己方(当前对象)
2. 转换函数
3. 对方(转换的目标类)
这三个需要在同一个作用域内才能生效吗?举个简单的例子,依然是java HashSet隐式转换为scala Set(可以参看本系列(3)),我们只是在要用到转换的文件里写了一行:
import scala.collection.JavaConverters._
也就是说导入了JavaConverters单例中的全部转换函数,但是我们并没有导入转换的目标类AsScala,所以按道理来说当前解释器并不知道AsScala的存在,就更不知道asScala方法要去哪寻找了。所以我们换一种思路,解释器的执行顺序也许是样:
1. 发现某个对象上调用了不存在的方法f
2. 以该对象为输入参数寻找所有的隐式转换函数
3. 列出所有隐式转换函数的输出参数类
4. 看看这些类中是否有方法f;如有,则执行转换;没有则报错。
因此我们可以回答所提出的问题了:并不需要三者在同一作用域内才能生效,只需要原对象、转换函数,就能触发隐式转换。
二. 隐式转换遇到继承类怎么办?
例如
class SmartAnimal (n:String){
val name = n
}
class Person (n:String) extends SmartAnimal(n) {
override val name = n
}
object converter {
implicit def asDog(person: Person):Dog = {
print("from Person to Dog")
new Dog(person.name + "_dog")
} implicit def asDog(animal:SmartAnimal):Dog = {
print("from SmartAnimal to Dog")
new Dog(animal.name)
}
}
def main(args: Array[String]) = {
var a = new Person("aaa")
a.bark
}
输出:
from Person to Dog
wang, wang, wang...
可以看到,隐式转换会尽可能优先将原对象转换到子类。但是如果我们把上边的子类转换方法注释掉呢?
object converter {
// implicit def asDog(person: Person):Dog = {
// print("from Person to Dog\n")
// new Dog(person.name + "_dog")
// } implicit def asDog(animal:SmartAnimal):Dog = {
print("from SmartAnimal to Dog\n")
new Dog(animal.name)
}
}
执行结果
from SmartAnimal to Dog
wang, wang, wang...
子类无法转换,则转换为父类。所以我们可以总结得出,scala中的隐式转换有多个有继承目标类可选时,是自下而上的,从子类往父类去找。
三、传值参数与传名参数
形式:
def funByName(arg: =>Int) = println(arg)//传名参数
def funByValue(arg:Int) = println(arg)//传值参数
注意传名参数的:和=之间一定要有空格!!!
在所传的参数为一个值(变量、常量)时,传名和传值并没有什么区别;只有当传递的为函数调用时,才会显现出差别:
传值参数将需要的参数调用计算完成之后,再将计算的结果作为一个单一的值输入函数运行(只算一次);
传名函数先将参数(需要执行的函数)传入函数体内,在需要用到该值的时候再执行(可能会算多次)。
看起来像是没什么区别是吧?请考虑这种情况,在某个类的方法中需要重复用到该参数,而该参数所传入的调用的函数每次返回的结果都不一样:
def pTimeByValue(time:Long) = {
for(i <- 1 to 5){
println(time)
Thread.sleep(1333)
}
}
def pTimeByName(time: =>Long) = {
for(i <- 1 to 5){
println(time)
Thread.sleep(1333)
}
}
def main(args: Array[String]) = {
println("按值传递打印五次时间:")
pTimeByValue(System.currentTimeMillis())
println("-------------------------\n按名传递打印五次时间:")
pTimeByName(System.currentTimeMillis())
}
执行结果
按值传递打印五次时间:
1535883761362
1535883761362
1535883761362
1535883761362
1535883761362
-------------------------
按名传递打印五次时间:
1535883768056
1535883769390
1535883770723
1535883772057
1535883773391
二者之间的区别足够清晰且一目了然了吧~简单来说,
按值传递——劳动一次,享受一生
按名传递——每次都要自己动手
scala成长之路(5)问题记录的更多相关文章
- scala成长之路(7)函数进阶——可能是史上最浅显易懂的闭包教程
由于scala中函数内部能定义函数,且函数能作为函数的返回值,那么问题来了,当返回的函数使用了外层函数的局部变量时,会发生什么呢?没错,就产生是闭包. 关于闭包的解释网上一大堆,但基本上都是照葫芦画瓢 ...
- scala成长之路(6)函数入门
众所周知,scala作为一门极客型的函数式编程语言,支持的特性包括: 函数拥有“一等公民”身份: 支持匿名函数(函数字面量) 支持高阶函数 支持闭包 部分应用函数 柯里化 首先需要指出,在scala中 ...
- scala成长之路(4)compaion object——伴生对象的使用
虽然java一直声称自己是完全面向对象的语言,但一直以来都被很多人所质疑,其中java的静态成员函数就是主要的“罪魁祸首”.由于java中保留了静态方法的调用,导致其编程模式依然有过程式编程的可能,尤 ...
- scala成长之路(3)隐式转换
不废话,先上例子:定义一个参数类型为String的函数: scala> def sayHello(name:String) = println("hello " + name ...
- scala成长之路(2)对象和类
scala提供了一种特殊的定义单例的方法:object关键字 scala> object Shabi{ | val age = 0 | val name = "shabi" ...
- scala成长之路(1)基本语法和数据类型
scala作为JVM上的Lisp,是一种geek类型的编程语言,也一直是我等java程序员眼中的梦寐以求的一门技能,遂下定决心花一段时间好好学习scala.第一天学习,主要介绍与java在编程上的主要 ...
- 架构师成长之路6.5 DNS服务器搭建(添加记录、负载均衡、DNS视图)
点击返回架构师成长之路 架构师成长之路6.5 DNS服务器搭建(添加记录.负载均衡.DNS视图) 部署主DNS : 点击 部署从DNS : 点击 1.添加A记录.CNAME记录.MX记录.PTR记录 ...
- java 成长之路[轉載u]
分享总结title: java 成长之路tags:grammar_cjkRuby: true 经验差异 1-3年 要求 建议 3-5年 建议 5年+ 经验差异 最近一年比较忙,经历了创业公司的倒闭.这 ...
- java 成长之路
分享总结 title: java 成长之路 tags: grammar_cjkRuby: true 经验差异 1-3年 要求 建议 3-5年 建议 5年+ 经验差异 最近一年比较忙,经历了创业公司的倒 ...
随机推荐
- SharePoint2010 HTTP Error 503. The service is unavailable 解决方法
1.更改系统管理员用户密码前提 因为更改系管理员用户密码会影响到 "SharePoint2010"正常运行,所在尽量不要更改系统管理员用户的密码, 必须更改密码的话,需要注意以两点 ...
- SQL Server 2012安装配置(Part2 )
2 服务器安装 运行安装程序后,首先进入 SQL Server 安装中心.选择左侧导航树中的"安装"菜单项. 图2-1 SQL Server 安装中心 在右侧菜单中点击" ...
- Struts2的学习-属性驱动和模型驱动
1.新建空项目,并托管到码云 2.设立maven 3.设置pom.xml 4.建包 5.在java包里建立两个类 package com.nf.entity; public class User { ...
- Wi-Fi
AP就是一个无线的交换机,提供无线信号发射接收的功能 Wi-Fi是一种可以将个人电脑.手持设备(如PDA.手机)等终端以无线方式互相连接的技术 两个不一样的东西,无法比较的 你说的应该是无线路由器和无 ...
- thrift基本概念和实例
一.thrift可以做什么 thrift是一个跨语言通信的工具,支持的语言多,而且还提供服务器端的众多网络模型,使服务端的开发可以只专于服务本身的逻辑. 二.thrift重要概念 1.processo ...
- MySQL:数据库入门篇4
1. 视图 创建视图 create view 视图名字 as 查询sql语句; drop view 视图名字; alter view 视图名字 as 查询sql语句; 2. 触发器 1. 插入事件触发 ...
- BZOJ4520:[CQOI2016]K远点对(K-D Tree)
Description 已知平面内 N 个点的坐标,求欧氏距离下的第 K 远点对. Input 输入文件第一行为用空格隔开的两个整数 N, K.接下来 N 行,每行两个整数 X,Y,表示一个点 的坐标 ...
- TSP 模拟退火
TSP——模拟退火解法 都知道TSP是经典的NP问题,从一个点开始遍历所有点,不重复,求最短路径. 可以用枚举终点,跑流量为2的最小费用,图论来做,时间复杂度为 费用流已经用到堆优化了.显然点,边 ...
- css布局-响应式布局
响应式设计 .在不同设备上正常使用 .一般主要处理屏幕大小问题 .主要方法: .隐藏 + 折行 + 自适应空间 .rem/viewport/media query 第一个案例 <!DOCTYPE ...
- Eclipse插件的卸载和安装
Eclipse 卸载插件: 右下角会有卸载进度 卸载完后 然后需要重启 Eclipse安装插件 选择本地下载好的插件 点击 Ok 插件下载地址:https://jaist.dl.sourceforge ...