除去Scala的糖衣(13) -- Default Parameter Value
欢迎关注我的新博客地址:http://cuipengfei.me/
好久没有写博客了,上一次更新竟然是一月份。
说工作忙都是借口,咋有空看美剧呢。
这半年荒废掉博客说到底就是懒,惯性的懒惰。写博客这事儿,一丢掉就很久捡不起来。
闲话到此为止,下面进入正题。
Default parameter value,默认参数值。 这个很容易理解,给参数一个默认值,如果调用者不显式指明参数值,则使用默认值。如果显式指明了,那就用显式指明的值。
举个例子:
1 |
|
这个函数,如果我们不给它传参数,它就会打印hello world。就像这样:
1 |
|
如果给了参数:
1 |
|
则打印hello everybody。
这个语言特性都有哪些应用场景呢?
它经常用来避免过多的重载。一个很常见很典型的例子就是构造函数重载。
在Java中,为了让调用者能够比较容易的创建某个类的实例,我们通常会提供几个参数列表比较短的构造函数。而这些构造函数存在的唯一意义就是为了写死某几个参数值。而在Scala中,有了这个语言特性,我们就无需那么麻烦了。
那这个语言特性是如何实现的呢?实际上简单的一塌糊涂。
这样一段代码:
1 |
|
我们的Greeter类含有前面提到过的hello方法。在AnotherClass里调用了hello,并且没有显式指明参数值。
上面的Scala代码生成的bytecode反编译成Java是这样的:
1 |
|
可以看到,我们所定义的hello方法反编译出来看起来很普通,就是个接受一个参数的方法。
而在Greeter类中,编译器为我们加入了另一个方法hello$default$1,这个方法就是返回一个写死的字符串,其值为world。
在AnotherClass中调用hello时,写死的字符串被取到,然后传进了hello里。
这样,被调用者提供了参数的默认值,调用者在调用时取得该值,然后传入方法。
题外话
到这里我不禁联想起C#中的默认参数值的实现方式。
在C#中,默认参数的值会被编译成调用者的一个常量,而不是像Scala一样的由被调用者提供。
这样看起来貌似没啥区别,不就是写死的值换个地方吗?
其实不然,如果被调用者在A程序集内,调用者在B程序集内,那么A更新时,B就必须重新编译才能得到最新的默认值。也就是说,如果当前部署环境中同时存在A和B,而后我们拿一个新版的A来替换老的,这时B仍然在传递老的默认参数值给A。这样就会造成一些看似很诡异的行为偏差。
如果对C#的默认参数值的实现有兴趣,请看我很久很久之前写的博客
现在想来,C#这一语言特性的设计者为什么要把它设计成如此容易出错的样子呢?
思而不得其解。
除去Scala的糖衣(13) -- Default Parameter Value的更多相关文章
- Default Parameter Values in Python
Python’s handling of default parameter values is one of a few things that tends to trip up most new ...
- 《理解 ES6》阅读整理:函数(Functions)(一)Default Parameter Values
对于任何语言来说,函数都是一个重要的组成部分.在ES6以前,从JavaScript被创建以来,函数一直没有大的改动,留下了一堆的问题和很微妙的行为,导致在JavaScript中使用函数时很容易出现错误 ...
- python's default parameter
[python's default parameter] 对于值类型(int.double)的default函数参数,函数不会保存对默认类型的修改.对于mutable objectd类型的默认参数,会 ...
- JavaScript函数的默认参数(default parameter)
JavaScript函数的默认参数(default parameter) js函数参数的默认值都是undefined, ES5里,不支持直接在形参里写默认值.所以,要设置默认值,就要检测参数是否为un ...
- 去掉Scala的糖衣(4) -- Type Aliase
我的新博客地址:http://cuipengfei.me/blog/2013/12/23/desugar-scala-4/ Scala中有一个type关键字,用来给类型或者是操作起别名,用起来很是方便 ...
- [Python] Pitfalls: About Default Parameter Values in Functions
Today an interesting bug (pitfall) is found when I was trying debug someone's code. There is a funct ...
- 抹掉Scala的糖衣(14) -- Update Method
欢迎关注我的新博客地址:http://cuipengfei.me/ 在Scala中,名字叫做update的方法是有特殊作用的. 比如: 1 2 3 val scores = new scala.col ...
- scala学习手记13 - 类继承
在scala里,类继承有两点限制: 重写方法需要使用override关键字: 只有主构造函数才能往父类构造函数中传参数. 在java1.5中引入了override注解,但不强制使用.不过在scala中 ...
- default parameter value for ‘color’ must be a compile-time constant
定义了一个函数,函数有一个参数是Color类型的可选参数,想要设置其默认值为Color.Black http://stackoverflow.com/questions/2804395/c-sharp ...
随机推荐
- 即将来到: CSS Feature Queries (CSS特性查询)
Feature Queries 是CSS3 Conditional Rules specification中的一部分,它支持“@supports”规则,“@supports”规则可以用来测试浏览器是否 ...
- source insight中{}自动缩进的调整
默认的自动缩进非常难看,解决方法如下: 菜单栏 -> Options -> document options ->点击右侧的 “Auto Indent...”按钮 将右侧" ...
- xcode 模拟器,文档,离线安装
一:xcode上的模拟器,文档,在下载时,通过apple.com下载的速度太慢了,所以我们下载之后,做一下备份,离线安装还原就行了! 二:模拟器安装 目录:/Users/<user name&g ...
- cocos2d-x eclipse + NDK 自动编译配置
文章来自:http://www.cocos2dres.com/view.asp?id=90 1. 准备工作: android NDK r8版本 ADT Bundle 下载地址:http://de ...
- Laravel 隐藏域如何实现?
Laravel 隐藏域如何实现? 在 Blade 模板中,我们可以使用 method_field 方法来创建隐藏域. {{ method_field('DELETE') }} 其转化为 HTM ...
- activiti自己定义流程之Spring整合activiti-modeler实例(七):任务列表展示
1.通过上一节的操作,能够知道流程启动以后会同一时候生成一个流程实例和用户任务.这个用户任务保存在act_ru_task和act_hi_task表中,从表明能够看出ru是runtime,hi是hist ...
- 〖Android〗把CM(Android)源代码导入eclipse的正确方法(2013-7-3)
1. 首先应当使CM代码成功编译过一次: cd /path/to/cm . build/envsetup lunch full-eng mka 2. 配置eclipse开发的基本环境 cd /path ...
- 逻辑回归的相关问题及java实现
本讲主要说下逻辑回归的相关问题和详细的实现方法 1. 什么是逻辑回归 逻辑回归是线性回归的一种,那么什么是回归,什么是线性回归 回归指的是公式已知,对公式中的未知參数进行预计,注意公式必须是已知的,否 ...
- MS SQL自定义函数IsPositiveInteger MS SQL自定义函数IsNumeric 水晶报表使用IEnumerable<T>数据源
MS SQL自定义函数IsPositiveInteger 判断字符串是否为正整数,0开始的的数字不算. SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON ...
- jquery 属性操作 attr( ) prop()css( )区别
一 attr () 和 prop( ) 操作属性 谈谈我的总结: 1 2 1 属性的定义,根据W3C手册所述:属性包括,标准属性:id class style title 语言属性 lang dir以 ...