欢迎关注我的新博客地址:http://cuipengfei.me/

好久没有写博客了,上一次更新竟然是一月份。

说工作忙都是借口,咋有空看美剧呢。

这半年荒废掉博客说到底就是懒,惯性的懒惰。写博客这事儿,一丢掉就很久捡不起来。

闲话到此为止,下面进入正题。

Default parameter value,默认参数值。 这个很容易理解,给参数一个默认值,如果调用者不显式指明参数值,则使用默认值。如果显式指明了,那就用显式指明的值。

举个例子:

1
def hello(name: String = "world") = println("hello " + name)

这个函数,如果我们不给它传参数,它就会打印hello world。就像这样:

1
hello()

如果给了参数:

1
hello("everybody")

则打印hello everybody。

这个语言特性都有哪些应用场景呢?

它经常用来避免过多的重载。一个很常见很典型的例子就是构造函数重载。

在Java中,为了让调用者能够比较容易的创建某个类的实例,我们通常会提供几个参数列表比较短的构造函数。而这些构造函数存在的唯一意义就是为了写死某几个参数值。而在Scala中,有了这个语言特性,我们就无需那么麻烦了。

那这个语言特性是如何实现的呢?实际上简单的一塌糊涂。

这样一段代码:

1
2
3
4
5
6
7
class Greeter {
def hello(name: String = "world") = println("hello " + name)
} class AnotherClass {
new Greeter().hello()
}

我们的Greeter类含有前面提到过的hello方法。在AnotherClass里调用了hello,并且没有显式指明参数值。

上面的Scala代码生成的bytecode反编译成Java是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Greeter {
public void hello(String name) {
Predef..MODULE$.println(new StringBuilder().append("hello ").append(name).toString());
} public String hello$default$1() {
return "world";
}
} public class AnotherClass {
public AnotherClass() {
Greeter qual$1 = new Greeter();
String x$1 = qual$1.hello$default$1();
qual$1.hello(x$1);
}
}

可以看到,我们所定义的hello方法反编译出来看起来很普通,就是个接受一个参数的方法。

而在Greeter类中,编译器为我们加入了另一个方法hello$default$1,这个方法就是返回一个写死的字符串,其值为world。

在AnotherClass中调用hello时,写死的字符串被取到,然后传进了hello里。

这样,被调用者提供了参数的默认值,调用者在调用时取得该值,然后传入方法。

题外话

到这里我不禁联想起C#中的默认参数值的实现方式。

在C#中,默认参数的值会被编译成调用者的一个常量,而不是像Scala一样的由被调用者提供。

这样看起来貌似没啥区别,不就是写死的值换个地方吗?

其实不然,如果被调用者在A程序集内,调用者在B程序集内,那么A更新时,B就必须重新编译才能得到最新的默认值。也就是说,如果当前部署环境中同时存在A和B,而后我们拿一个新版的A来替换老的,这时B仍然在传递老的默认参数值给A。这样就会造成一些看似很诡异的行为偏差。

如果对C#的默认参数值的实现有兴趣,请看我很久很久之前写的博客

现在想来,C#这一语言特性的设计者为什么要把它设计成如此容易出错的样子呢?

思而不得其解。

最新文章

  1. Rxjava Subjects
  2. PHP中的数据库一、MySQL优化策略综述
  3. 如何在没有域的环境中搭建AlwaysOn(二)
  4. Atiti.ui原理与gui理论
  5. source insight 里编辑的时候,每次粘贴后,光标停留在粘贴内容的左面
  6. AngularJs记录学习02
  7. PB中获取datawindow提交的sql语句
  8. Careercup - Facebook面试题 - 6299074475065344
  9. C语言-06复杂数据类型-02字符串
  10. 水平/竖直居中在旧版Safari上的bug
  11. UNION ALL vs UNION
  12. JMS-activeMQ
  13. Redis 优化查询性能
  14. 查询全国的省市信息<option>拼接
  15. 判断是ios还是android
  16. JVM学习之类加载
  17. 浅谈SQL优化入门:2、等值连接和EXPLAIN(MySQL)
  18. C#基础拾遗系列之一:先看懂IL代码
  19. XOR (莫队)
  20. Delphi基础-数据类型

热门文章

  1. Cg入门21:Fragment shader - 2D纹理採样
  2. ant design pro (四)新增页面
  3. js 替换json对象中的键名
  4. 编程算法 - 翻转单词顺序 代码(C)
  5. 关于RDS备份文件使用wget下载提示403 Forbidden的情况
  6. C++:模板友元
  7. storm trident merger
  8. Python 爬虫 去掉网页注释,去掉网页注释
  9. windows gvim插入当前时间
  10. PCI总线 DMA burst 基本概念