为什么scala函数限制为22个参数?

Jac*_*vis 35 scala

并不是说我实际上接近这个限制,但我总是想知道:为什么他们停在Function22/ Tuple22.JVM限制?任意选择?

The*_*heo 29

功能和元组被改写为被编译器的对象,并且仅Function0通过Function22Tuple0通过Tuple22被定义.我认为22的限制完全是任意的,但限制的原因不是.

可以这样想:运行Scala应用程序必须存在运行它所需的类.如果编译器会动态创建函数类,那么这些类将不会包含在Scala库JAR中,因此您必须将它们包含在应用程序中.这可能有用,但是你会遇到类的完全限定名称应该是什么问题:如果它们对于所有应用程序都是相同的那么你会发生冲突,因为库将包含相同的类,如果名称不是同样你最终会遇到不兼容问题 - 库中的函数与应用程序中的函数不同.

  • @DarianLewin`Tuple0`被称为`Unit` (9认同)
  • 它实际上是Tuple1到Tuple22,但这只是一个小细节. (3认同)
  • 关于为什么这些类不应该由编译器动态生成,仍然不是很确定。遵循命名约定,可以轻松解决命名和包装问题。不知道我是否错过了全局。 (2认同)

Apo*_*isp 25

没有这样的限制.即使标准库仅定义了Function22,您也可以根据需要定义Function23,最高可达JVM限制.或者您可以将参数分组为元组.或者你可以停止假装任何函数需要多个参数:

a => b => c => d => e => ...
Run Code Online (Sandbox Code Playgroud)

Curried函数可以根据需要使用尽可能多的参数,直到堆栈大小的限制.


Kev*_*ght 11

它几乎是随意的,但是JVM 一些潜在的限制,它们大致规定了限制需要的限制.

主要问题是案例类的模式匹配.如果允许案例类大得多,则生成的模式匹配代码可能很容易超过最大有效方法大小.其他所有(产品,功能,元组,......)只是遵循因为案例类选择的22参数限制.

另外......如果您正在编写带有> 22个参数的函数/元组,那么您可能已经过期了重新设计:)

  • 有时它不是你的设计.假设您正在编写一个案例类来表示具有22个以上参数的网络协议消息.或解析您无法控制的服务器的JSON响应. (20认同)

Mar*_*lic 7

极限22已经下降在疯疯癫癫(斯卡拉3)删除功能22限制#1758

函数类型的最大参数数和元组类型中的最大字段数的 22 限制已被删除。

函数现在可以有任意数量的参数。超出Function22的函数被擦除为新特征scala.FunctionXXL,超出Tuple22的元组被擦除为新特征scala.TupleXXL。这两个都是使用数组实现的。

例如,

object drop22limit extends App {
  val f23 = (x1: Int, x2: Int, x3: Int, x4: Int, x5: Int, x6: Int, x7: Int, x8: Int, x9: Int, x10: Int, x11: Int, x12: Int, x13: Int, x14: Int, x15: Int, x16: Int, x17: Int, x18: Int, x19: Int, x20: Int, x21: Int, x22: Int, x23: Int) => x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23
  val result = f23(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
  println(result)
}
Run Code Online (Sandbox Code Playgroud)

输出276。有关任意元组和函数之间相互作用的示例,请参阅添加通用元组函数抽象 #6568


Lan*_*dei 5

随意选择。即使这些类是自动生成的,也必须在某处存在限制。

请注意,您可以使用 HLists 或类似的结构来获得类似“任意大小的元组”的内容(请参阅http://jnordenberg.blogspot.com/2008/08/hlist-in-scala.html