scala学习手记27 - 下划线与参数
在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 - 下划线与参数的更多相关文章
- scala学习手记21 - 传递变长参数
在Java中是可以使用变长参数的,如下面的方法: public void check(String ... args){ for(String tmp : args){ System.out.prin ...
- 六、Django学习之基于下划线的跨表查询
六.Django学习之基于下划线的跨表查询 一对一 正向查询的例子为 已知用户名,查询用户的电话号码.反向查询例子反之. 正向查询 其中下划线前的表示表名,无下划线的表示的是Author表 resul ...
- scala学习手记38 - 方法命名约定和for表达式
方法命名约定 之前在学习<运算符重载>一节时曾经说过一个方法命名约定:方法的第一个字符决定了方法的优先级.现在再说另一个命名约定:如果方法以冒号(:)结尾,则调用目标是运算符后面的实例. ...
- scala学习手记17 - 容器和类型推断
关于scala的类型推断前面已经提到过多次.再来看一下下面这个例子: import java.util._ var list1: List[Int] = new ArrayList[Int] var ...
- scala学习手记39 - 模式匹配
在java中有switch/case这样的模式匹配语句,可以匹配的类型包括int,byte,char,short, enum,在java8又支持了字符串. 在scala中也有类似的模式匹配语句,即ma ...
- scala学习手记36 - 容器基础
scala的容器包括Set.List和Map.三种容器的特征和Java中一样.scala为每种容器都提供了可变和不可变两种版本,分别位于scala.collection.mutable或scala.c ...
- scala学习手记12 - 字段、方法和构造函数
在上一节创建了一个scala类,如果没有更多的方法,scala类的定义还可以更简单一些,看一下下面这个CreditCard类的定义: class CreditCard(val number: Int, ...
- scala学习手记24 - 多参数函数值
上一节的函数值只有一个参数.函数值当然也是可以有多个参数的.看一下下面的inject方法: def inject(arr: Array[Int], initial: Int, operation: ( ...
- scala学习手记23 - 函数值
scala的一个最主要的特性就是支持函数编程.函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套.这些高阶函数称为函数值. 举一个简单的例子 ...
随机推荐
- 170221、浅谈mysql的SQL的四种连接
例子: ------------------------------------------------- a表 id name b表 id job pare ...
- canvas基本使用
1.什么是CANVAS canvas是html5新增的画布元素,可以通过javascript来在画布上绘制图形,图标以及任何视觉性的图像. 2.canvas的用途 替代flash,做各种动态效果,做小 ...
- Unicode 和 UTF-8 是什么关系?
2015-10-14 10:08 评论: 9 收藏: 4 转载自: http://huoding.com/2015/10/13/472作者: 火丁笔记本文地址:https://linux.cn/ ...
- caffe杂
一.finetune命令: mpirun /home/zhangsuosheng/caffe_mpi/build/tools/caffe train -solver solver.prototxt - ...
- 删除DOM元素 parent.removeChild(target)
p.removeChild(p.children[0]);
- Python--(并发编程之线程Part2)
GIL只能保证垃圾回收机制的安全,进程中的数据安全还是需要自定义锁 线程执行代码首先要抢到GIL全局锁,假设线程X首先抢到,以为要抢到自定义锁要执行代码,所以这个线程在执行代码的时候就很容抢到了自定义 ...
- 如何实现redis集群?
由于Redis出众的性能,其在众多的移动互联网企业中得到广泛的应用.Redis在3.0版本前只支持单实例模式,虽然现在的服务器内存可以到100GB.200GB的规模,但是单实例模式限制了Redis没法 ...
- 自己定义图片的progressbar
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zpf8861/article/details/36183455 Android系统自带的Progre ...
- 快速排序算法Java版
网上关于快速排序的算法原理和算法实现都比较多,不过java是实现并不多,而且部分实现很难理解,和思路有点不搭调.所以整理了这篇文章.如果有不妥之处还请建议.首先先复习一些基础. 1.算法概念. ...
- LeetCode:组合总数III【216】
LeetCode:组合总数III[216] 题目描述 找出所有相加之和为 n 的 k 个数的组合.组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字. 说明: 所有数字都是正整数. ...