美文网首页
匿名类函数的占位符语法

匿名类函数的占位符语法

作者: Azur_wxj | 来源:发表于2018-02-19 21:22 被阅读18次

匿名类函数的占位符语法

考虑下面的代码:

val numSeq=Array(3.1415,2.71828,9.8)

下面想用foreach方法输出它们的整数,如果用占位符语法,比如下面这样:

scala> numSeq foreach (println(_.toInt))

<console>:13: error: missing parameter type for 
  expanded function ((x$1: <error>) => x$1.toInt)
     numSeq.foreach(println(_.toInt))
                            ^

看起来,我们本意是将println(_.toInt)解释为x=>println(x.toInt),但是编译器却理解为x=>x.toInt,自然不对。这是因为,添加了一对括号后((_.toInt))就形成了新的词法作用域,因此println(_.toInt)会被解读为println(x=>x.toInt)
(参考:Scala placeholder syntax for anonymous function

既然如此,不妨去掉括号看看:

scala> numSeq foreach (println_.toInt)  没有加空格
<console>:13: error: not found: value println_
       numSeq foreach (println_.toInt)
                       ^

很容易错的地方,就是在函数名和下划线之间不加空格,这就会将println_看做一个标识符。

scala> numSeq foreach (println _.toInt)
<console>:1: error: ')' expected but '.' found.
       numSeq foreach (println _.toInt)

注意,scala里面,使用method()可以简写为method,但是method(x)不能省略括号method x (错误)。(这是Groovy的语法,搞混了_(:зゝ∠)_)
有一个特殊的下划线用法,也就是说,指代整个参数列表,就可以写成method _,所以,println _.toInt事实上是println _,显然后跟.toInt就不合理了,因为这就变成( x=>println(x) ).toInx,语法错误。

那么该怎么做呢?注意到在scala里,如果对象obj调用一个方法method,而该方法只接受一个参数x,那么obj.method(x)可以简写为obj method xobj method (x),看起来method就不是一个方法名而是一个中缀操作符,换言之

scala> numSeq foreach (Console println _.toInt)
3
2
9

此时,编译器明确是三部分,所以_.toInt就被视为一个整体,从而Console println _.toInt就被翻译成我们需要的x=>Console.println(x,toInt)

现在想要将numSeq升序排序:

scala> numSeq.sortWith{ _.compareTo(_)<0 }
res93: Array[Double] = Array(2.71828, 3.1415, 9.8)

_.compareTo(_)<0实际上是(x,y) => { x.compareTo(y)<0 }

更多参考:scala 下划线解析报错: missing parameter type for expanded func

下划线文法的就近展开原则原则:

Underscores extend outwards to the closest closing Expr : top-level expressions or expressions in parentheses

匿名函数简写注意事项:
所以当匿名函数有多个括号嵌套的时候,不要使用_的简写方式 ,而应该用普通匿名函数的书写方式。比如 (x:Int,y:Int)=> (x*2)+f(y+2)

_本身构不成一个表达式:expressions,所以如下是允许的scala> List(1,2,3,4).foreach(print(_)) => List(1,2,3,4).foreach(print _) => List(1,2,3,4).foreach(print) => List(1,2,3,4) foreach print => List(1,2,3,4) foreach print _

相关文章

  • 匿名类函数的占位符语法

    匿名类函数的占位符语法 考虑下面的代码: 下面想用foreach方法输出它们的整数,如果用占位符语法,比如下面这样...

  • Scala拾遗(目录汇编)

    1、匿名类函数的占位符语法 2、Unit和() 3、命令行下相关操作 4、Java与Scala的容器转换 5、Sc...

  • 匿名函数1

    匿名函数 匿名函数指一类无须定义标识符的函数或子程序。Python用lambda语法定义匿名函数,只需用表达式而无...

  • 随记

    MySQL与 PostgreSQL 预处理(Prepared) 匿名占位符 MySQL: 使用 ? 作为匿名占位符...

  • C++11新特性--lambda

    匿名函数--lambda函数     匿名函数或者匿名类这种语法在其他语言(如lisp,java中)早有应用。在C...

  • Swift -- 10.泛型&集合

    一.泛型语法 1.函数中使用泛型 泛型的基本语法,首先我们要指定一个占位符T(占位符也可以为其它字符),紧挨着写在...

  • 02.语言元素

    1. 变量和类型 说明:上面的print函数中输出的字符串使用了占位符语法,其中%d是整数的占位符,%f是小数的占...

  • Golang理解 匿名函数

    匿名函数 匿名函数(英语:Anonymous Function)在计算机编程中是指一类无需定义标识符(函数名)的函...

  • Dart 2.1 的细节笔记总结(二)

    => (胖箭头) 简写语法用于仅包含一条语句的函数。该语法在将匿名函数作为参数传递时非常有用: 类 扩展类(继承)...

  • swift 泛型

    泛型是为Swift编程灵活性的一种语法,在函数、枚举、结构体、类中都得到充分的应用,它的引入可以起到占位符的作用,...

网友评论

      本文标题:匿名类函数的占位符语法

      本文链接:https://www.haomeiwen.com/subject/sorwtftx.html