You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala方法调用语法疑问:foldLeft与{}、()用法解析

问题解答

1. 关于代码中r和l的类型疑问

先拆解你写的代码里的语法陷阱:

val r = List(1, 2, 3).foldLeft(0) _+_

这段代码的语法解析和你预期的完全不一样!Scala的运算符优先级和占位符_的作用在这里产生了歧义:

  • 你可能以为是把foldLeft(0)和_+_(即(a,b) => a+b)结合,但实际上,foldLeft(0) _是部分应用函数——它表示只传入foldLeft的第一个参数0,返回一个等待第二个参数(即累加函数(Int,Int)=>Int)的函数,类型是((Int, Int) => Int) => Int。
  • 而后面的+_被解析成了字符串拼接的匿名函数:因为Scala中函数的toString方法会返回类似$Lambda$xxx@xxx的字符串,当你写(foldLeft(0) _) + _时,_是参数占位符,整个表达式等价于:
    val r = (x: String) => (List(1,2,3).foldLeft(0) _).toString + x
    
    这就是为什么r的类型是String => String——它是一个接收字符串、返回函数字符串和输入字符串拼接结果的函数。

再看第二行:

val l = r{"hello"}

这里的r{"hello"}其实等价于r("hello")(Scala中,当方法/函数只有一个参数时,可以用大括号代替括号),所以调用r时传入了"hello",返回的是(foldLeft(0) _)的字符串表示加上"hello",也就是你看到的$Lambda$1643/1458648440@23ae6386hello——l根本不是函数,而是一个字符串,自然无法调用。

如果你的真实意图是用foldLeft计算累加和,正确的写法应该是:

// 两种正确写法
val sum1 = List(1,2,3).foldLeft(0)(_+_)
val sum2 = List(1,2,3).foldLeft(0){_+_}

2. Scala中()和{}的官方参考文档

Scala官方有明确的文档说明两者的区别和使用场景:

  • Scala语言规范(Scala Language Specification):在"Expressions"章节里,详细定义了括号表达式(Parenthesized Expressions)和块表达式(Block Expressions)的语法规则,包括方法调用时参数列表的括号与大括号的差异——比如块表达式可以包含多行代码、声明变量等,而括号里只能是单个表达式。
  • Scala风格指南(Scala Style Guide):专门有一节讲解何时使用括号、何时使用大括号:
    • 当方法接收单个匿名函数参数时,优先用大括号(尤其是函数体有多行时);
    • 当方法参数是多个值或简单表达式时,用括号;
    • 无参数的方法,如果是纯函数(无副作用)可以省略括号,有副作用(比如打印、修改状态)则建议保留括号。

内容的提问来源于stack exchange,提问作者WesleyHsiung

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:03:17