在Scala里,下划线(_)可以表示函数值的参数。如果某个参数在函数里仅使用一次,就可以用下划线表示。每次在函数里用下划线,都表示随后的参数。

val arr = Array(1, 2, 3, 4, 5)
println("Sum of all values in array is " + (0 /: arr) { (sum, elem) => sum + elem })

上面的代码里使用了“/:”方法。这个方法的意思大致上是从数组的左侧开始迭代运算。这里是用来计算数组中所有元素的和。因为在函数值中sum和elem只用了一次,所以这个函数也可以这样写:

val arr = Array(1, 2, 3, 4, 5)
println("Sum of all values in array is " + (0 /: arr) {_+_} )

其中第一个“_”就是sum,即用来迭代运算的值;第二个“_”表示的是数组中的元素。这里是一处让人比较纠结的地方,是要简洁还是要可读性都得自己选择了(这次我偏向于简洁,因为熟悉scala以后理解这里应该不是问题)。如果能在不失可读性又足够简洁的地方使用就最好了,来看一下下面的例子:

val negativeNumberExists = arr.exists { _ < 0 }
println("Array has negative number? " + negativeNumberExists)

这里的代码用来查找数组中是否有小于0的元素。

在某些有意义的地方,这种简洁还可以更进一步。比如说我们想从一个数组中找出最大值。从这个需求出发,我们会一步步地简化实现的函数。最开始是这个样子的,我们使用了“/:”方法:

def max(a: Int, b: Int) = {
if (a > b)
a
else
b
}
println("Max value in array is " + (Int.MinValue /: arr) { (large, ele) => max(large, ele) })

用下划线表示函数值参数来做一次简化:

println("Max value in array is " + (Int.MinValue /: arr) { max(_, _) })

“_”不仅可以表示一个参数,还可以表示整个参数列表。这样的话就可以简化成这样:

println("Max value in array is " + (Int.MinValue /: arr) { max _ })

在上面的代码里,“_”表示整个参数列表。如果只是把参数传递给下层的方法(拿的原文,有疑义,什么是下层的方法),甚至可以省下使用“_”。上面的代码可以简化为:

println("Max value in array is " + (Int.MinValue /: arr) { max })

可以看到,依赖类型推断,scala的简洁到了丧心病狂(无贬义)的程度。这也给开发者留下了一个难题:需要适当克制自己简化代码的欲望,留下适当的可读性,不让代码变成天书。

################

scala学习手记27 - 下划线与参数的更多相关文章

  1. scala学习手记21 - 传递变长参数

    在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.prin ...

  2. 六、Django学习之基于下划线的跨表查询

    六.Django学习之基于下划线的跨表查询 一对一 正向查询的例子为 已知用户名,查询用户的电话号码.反向查询例子反之. 正向查询 其中下划线前的表示表名,无下划线的表示的是Author表 resul ...

  3. scala学习手记38 - 方法命名约定和for表达式

    方法命名约定 之前在学习<运算符重载>一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级.现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例. ...

  4. scala学习手记17 - 容器和类型推断

    关于scala的类型推断前面已经提到过多次.再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var ...

  5. scala学习手记39 - 模式匹配

    在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串. 在scala中也有类似的模式匹配语句,即ma ...

  6. scala学习手记36 - 容器基础

    scala的容器包括Set.List和Map.三种容器的特征和Java中一样.scala为每种容器都提供了可变和不可变两种版本,分别位于scala.collection.mutable或scala.c ...

  7. scala学习手记12 - 字段、方法和构造函数

    在上一节创建了一个scala类,如果没有更多的方法,scala类的定义还可以更简单一些,看一下下面这个CreditCard类的定义: class CreditCard(val number: Int, ...

  8. scala学习手记24 - 多参数函数值

    上一节的函数值只有一个参数.函数值当然也是可以有多个参数的.看一下下面的inject方法: def inject(arr: Array[Int], initial: Int, operation: ( ...

  9. scala学习手记23 - 函数值

    scala的一个最主要的特性就是支持函数编程.函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套.这些高阶函数称为函数值. 举一个简单的例子 ...

随机推荐

  1. J2EE知识体系(简单整理)

  2. 巨蟒python全栈开发-第24天 内置常用模块3

    一. 1.re模块基础知识 2.python模块&re正则模块 3.实战:re模块&python(链家&电影天堂&豆瓣) 复习:上节课重点(1)sys.path 模块的 ...

  3. Powershell&.NET数值取整处理

    如何取一个数的整数值? 使用类型强制转换 Powershell的强制转换有2种方式,一种是直接类型强制转换,另一种是通过-as运算符进行转换 PS F:\> [int] (3 / 2) # 直接 ...

  4. xshell上传下载文件

    上传文件到服务器rz 从服务器下载文件sz

  5. 【我的Android进阶之旅】Realm数据库学习资料汇总(持续更新)

    介绍 realm是一个跨平台移动数据库引擎,支持iOS.OS X(Objective-C和Swift)以及Android. 2014年7月发布.由YCombinator孵化的创业团队历时几年打造,是第 ...

  6. ie6不能播放视频问题

    前几天做项目时碰到一个非常棘手的问题.在我自己本机的ie8上能正常播放视频的程序(ie6也能够),放用户的电脑上就是不能正常播放(可能是用户的机子系统太老或是别的什么原因.详细的我也不太清楚).没办法 ...

  7. N多条短信,用什么算法从中找出相似内容的来?

    创建树,每个字符为一个节点,对于同一位置字符相同的共用一个节点.最后找出具有公共节点的短信.例如:MessageA "hello,world"MessageB "hell ...

  8. 学点TCPDUMP

    [root@future ~]# yum install tcpdump 官网地址: https://nmap.org/ 还有中文手册,太感动了 https://nmap.org/man/zh/man ...

  9. Python Static Method

    How to define a static method in Python?Demo: #!/usr/bin/python2.7 #coding:utf-8 # FileName: test.py ...

  10. s5_day2作业

    # 1:编写for循环,利用索引遍历出每一个字符 # msg = 'hello egon 666' # for i in range(len(msg)): # print(i,msg[i]) # 2: ...