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的一个最主要的特性就是支持函数编程.函数是函数编程中的一等公民:函数可以作为参数传递给其他函数,可以作为其他函数的返回值,甚至可以在其它函数中嵌套.这些高阶函数称为函数值. 举一个简单的例子 ...
随机推荐
- 《JAVA多线程编程核心技术》 笔记:第四章、Lock的使用
一.使用ReentrantLock类1.1 ReentrantLock的使用:1.2 ReentrantLock的不足:1.3 正确使用Condition实现等待/通知1.4 使用多个Conditio ...
- ZOJ 3661 Palindromic Substring(回文树)
Palindromic Substring Time Limit: 10 Seconds Memory Limit: 65536 KB In the kingdom of string, p ...
- python抓取网页中的动态数据
一.概念 网页中的许多数据并不是写死在HTML中的,而是通过js动态载入的.所以也就引出了什么是动态数据的概念,动态数据在这里指的是网页中由Javascript动态生成的页面内容,是在页面加载到浏览器 ...
- Powershell Get-registerkey(susid)
$servers=get-content D:\serverregister.txt Get-registerkey -ComputerName $servers | select computer, ...
- jd算法大赛 一个user_id只需映射到一个sku_id, 但是一个sku_id能否映射到多个user_id
0-购买预测 w 任务目标 提交user_id-->sku_id (1->1,但反向呢?) 实际操作: 0- 行为表中的type值加权为一个购买意向值0(性别.年龄,不干扰/或加权) 品类 ...
- numpy.random.random & numpy.ndarray.astype & numpy.arange
今天看到这样一句代码: xb = np.random.random((nb, d)).astype('float32') #创建一个二维随机数矩阵(nb行d列) xb[:, 0] += np.aran ...
- 深入Redis内部-Redis 源码讲解(转)
Redis作为 NoSQL 数据库的杰出代表,一直广受关注,其轻量级的敏捷架构,向来有存储中的瑞士军刀之称.下面推荐的一篇文章,从源码的角度讲解了Redis 的整个工作流程,是了解 Redis 流程的 ...
- ios开发之手势动作状态细分state,同一视图加入两个手势
1.比方拖拽一个视图.形成类似scrollView的翻页形式 在拖拽的方法里推断拖拽的状态state属性,依据状态不同运行自己须要的效果. 2.同一视图加入两个手势,须要使用手势的代理方法.同意此操作 ...
- Grunt JS构建环境搭建以及使用入门
Grunt JS构建环境搭建以及使用入门 1.应用场景 一种自动化任务处理工具,对于日常的需求(代码规则检查.代码合并)可以实现自动化执行,只需要保留package.json和Gruntfile.js ...
- Delphi 正则表达式之TPerlRegEx 类的属性与方法(1): 查找
Delphi 正则表达式之TPerlRegEx 类的属性与方法(1): 查找 //查找是否存在 var reg: TPerlRegEx; begin reg := TPerlRegEx.Cre ...