Scala 2.12中fold方法函数字面量参数类型缺失问题问询
为什么Scala 2.12中
Try("3").fold(_.toString, _)会报错? 这个问题其实和Scala 2的类型推断规则对占位符语法的限制有关,咱们一步步拆解清楚:
首先,Try("3")的类型是Try[String],它的fold方法签名本质是这样的:
def fold[B](onFailure: Throwable => B, onSuccess: String => B): B
这个方法需要两个函数参数,最终返回类型B是由这两个函数的返回类型共同决定的。
为什么fold(_.toString, _.toString)能正常运行?
当你传入两个_.toString时:
- 第二个
_.toString对应onSuccess参数,编译器能直接从Try[String]知道这个函数的输入是String,String.toString()返回String,所以先推断出B = String。 - 接着看第一个
_.toString,对应onFailure参数,输入是Throwable,Throwable.toString()也返回String,正好符合B = String的要求,整个类型推断链条通顺,编译器能顺利通过。
为什么fold(_.toString, _)会报错?
问题出在第二个参数的_占位符语法上。Scala 2中,占位符_作为匿名函数的简写时,对类型推断的上下文要求更严格:
- 虽然第一个参数
_.toString已经能推断出B = String,但编译器在处理第二个参数的_时,无法直接关联到onSuccess需要的String => String类型。因为占位符_本身没有显式的参数声明,编译器没办法“回溯”利用已经推断出的B类型来确定这个匿名函数的参数类型,所以会抛出missing parameter type for expanded function的错误。
为什么fold(_.toString, x => x)能解决问题?
当你把_换成显式的x => x时,编译器可以利用已经从第一个参数推断出的B = String,自动推导x的类型是String,返回值也是String,完美匹配onSuccess的String => String类型要求,所以就能正常编译了。
简单总结:占位符_的类型推断不够“灵活”,没办法跨参数利用已推断的类型信息,而显式的匿名函数(比如x => x)能让编译器更清晰地完成类型推导。
内容的提问来源于stack exchange,提问作者david.perez
相关产品推荐
相关产品推荐

