加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

【Scala谜题】使用占位符

发布时间:2020-12-16 09:41:05 所属栏目:安全 来源:网络整理
导读:笔记来源: Scala谜题 Scala 特别强调要书写简单、简洁的代码。匿名函数的语法 arg = expr ,使它很容易用最小模板构建函数字面量,甚至函数由多个语句组成时也一样可以。 用有自解释参数的函数还可以做得更好,而且还可以用占位符语法。占位符语法可以省去
笔记来源: Scala谜题

Scala 特别强调要书写简单、简洁的代码。匿名函数的语法 arg => expr,使它很容易用最小模板构建函数字面量,甚至函数由多个语句组成时也一样可以。

用有自解释参数的函数还可以做得更好,而且还可以用占位符语法。占位符语法可以省去参数声明:

List(1,2).map { i => i + 1}

List(1,2).map { _ + 1}

以上两个语句是等价的。但如果使用如下语句:

List(1,2).map { i => println("Hi");i + 1 }

List(1,2).map { println("Hi"); _ + 1 }

会发现,它们的输出结果不一样:

Hi
Hi
List[Int] = List(2,3)

Hi
List[Int] = List(2,3)

为什么使用占位符语法的函数与预计结构不一样呢?因为匿名函数常常被当作参数传递,在代码中往往会看到它们在花括号 { ... } 里,就很容易认为这些花括号表示一个匿名函数。但是,实际上它们只是界定了一个块表达式,一个或多个表达式最后决定了这个块的结果。

两个代码块的解析方式决定了它们有不同的行为。第一个语句 { i => println("Hi"); i + 1 } 被当成一个 arg => expr 形式的函数字面量表达式,这里的表达式是块 println("Hi"); i + 1

第二个表达式中,代码块被认为是 println("Hi")_ + 1 两个表达式。当这个代码块执行的时候,将最后一个表达式(便利性所需的函数类型,Int => Int)传递给map。其中的println语句不是函数体的一部分,它是在map的参数评估时被调用的,而不是作为map的一部分执行。

将刚刚那两个函数拆分后可以很方便看出它们的区别:

scala> val printAndAddOne = (i: Int) => { println("Hi"); i + 1 }
printAndAddOne: Int => Int = <function1>

scala> List(1,2).map(printAndAddOne)
Hi
Hi
res29: List[Int] = List(2,3)
scala> val printAndReturnAFunc = { println("Hi"); (_: Int) + 1 }
Hi
printAndReturnAFunc: Int => Int = <function1>

scala> List(1,2).map(printAndReturnAFunc)
res30: List[Int] = List(2,3)
Scala 鼓励简洁的代码,但太简洁时就会出现这样的情况。使用占位符语法时一定要注意由它所创建的函数范围。

这里学到的一点是:用占位符语法定义的匿名函数的范围只延伸到含有下划线 _ 的表达式,而常规的匿名函数的函数体是包含从箭头标识符 => 一直到代码块结束的所有代码。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读