scala 下划线解析报错: missing parameter type for expanded function

本文首先介绍下eta-expansion概念,以及其对下划线的expand的解析规则和匿名函数简写注意事项,最后通过例子解析加深读者的理解
 
eta-expansion概念:
把 x => func(x) 简化为 func _ 或 func 的过程称为 eta-conversion 
把 func 或 func _ 展开为 x => func(x) 的过程为 eta-expansion

Eta Expansion的就近expand解析原则:

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

 

 

匿名函数简写注意事项:

 

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

 

 

 

 

 

例子解析:

 

例子1:

scala> List(1,2,3).map(_*2)
res6: List[Int] = List(2, 4, 6)
 
scala> List(1,2,3).map(_*2+1)
res14: List[Int] = List(3, 5, 7)
 
但是吧_*2 换成(_*2) 则出错,因为根据就近原则 _*2 会在最近的括号中解析成匿名函数 为(x$1) => x$1.$times(2),  变成为(x=>x*2) +1 , 而期望的是(x)=>(x*2)+1
scala> List(1,2,3).map((_*2)+1)
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.$times(2))
              List(1,2,3).map((_*2)+1)
                               ^
 
如果括号内只有_ 本身,则_本身构不成一个表达式expressions,所以如下是允许的
scala> List(1,2,3).map((_)+1)
res8: List[Int] = List(2, 3, 4)
 
 

例子2:

scala> List(1,2,3,4).foreach(print _)
1234
 
 
_本身构不成一个表达式 :expressions,所以如下是允许的
 
scala> List(1,2,3,4).foreach(print(_))
1234
 
(_.toString) 是一个在括号()里的表达式,会expand解析成匿名函数,而print期望的String类型的值,所以编译报错
scala> List(1,2,3,4).foreach(print(_.toString))
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.toString)
              List(1,2,3,4).foreach(println(_.toString))
                                            ^
 
 
 

例子3:
val myStrings = new Array[String](3)
// do some string initialization

// this works
myStrings.foreach(println(_))


// ERROR: missing parameter type for expanded function
myStrings.foreach(println(_.toString))

It expands to:

myStrings.foreach(println(x => x.toString))

You want:

myStrings.foreach(x => println(x.toString))

The placeholder syntax for anonymous functions replaces the smallest possible containing expression with a function.

 
 
 
keywords:error: missing parameter type for expanded function 
 
Eta Expansion
 
 
The usage of placeholder syntax for anonymous functions is restricted to expressions.
 
 
 
参考如下:
 

This has already been addressed in a related question. Underscores extend outwards to the closest closing Expr : top-level expressions or expressions in parentheses.

(_.toString) is an expression in parentheses. The argument you are passing to Exception in the error case is therefore, after expansion, the full anonymous function (x$1) => x$1.toString of type A <: Any => String, while Exception expects a String.

In the println case, _ by itself isn't of syntactic category Expr, but (println (_)) is, so you get the expected (x$0) => println(x$0).

 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值