为什么 Scala 函数限制为 22 个参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4152223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why are scala functions limited to 22 parameters?
提问by Hymanson Davis
Not that I've actually come close to that limit, but Ive always wondered: Why do they stop at Function22/Tuple22. JVM restriction? Arbitrary choice?
并不是说我实际上已经接近该限制,但我一直想知道:为什么他们停在Function22/ Tuple22。JVM限制?随意选择?
采纳答案by Theo
Functions and tuples are rewritten as objects by the compiler, and only Function0through Function22and Tuple0through Tuple22are defined. I think the limit of 22 is entirely arbitrary, but the reason for having a limit is not.
函数和元组被编译器重写为对象,并且只定义了Function0throughFunction22和Tuple0through Tuple22。我认为 22 的限制完全是任意的,但有限制的原因不是。
Think of it this way: to run a Scala application the classes needed to run it must be present. If the compiler would dynamically create classes for functions then those classes would not be included in the Scala library JAR, so you would have to include them in your application. That could work, but then you would have the problem of what the classes' fully qualified names should be: if they were the same for all apps then you would have clashes since libraries would contain the same classes, and if the names were not the same you would end up with incompatibilities -- functions from libraries wouldn't be the same as functions in your app.
可以这样想:要运行 Scala 应用程序,运行它所需的类必须存在。如果编译器会为函数动态创建类,那么这些类将不会包含在 Scala 库 JAR 中,因此您必须将它们包含在您的应用程序中。这可以工作,但是您会遇到类的完全限定名称应该是什么的问题:如果它们对于所有应用程序都相同,那么您会发生冲突,因为库将包含相同的类,并且如果名称不是同样,您最终会遇到不兼容问题——库中的函数与您的应用程序中的函数不同。
回答by Apocalisp
There is no such limit. Even if the standard libraries only define up to Function22, you can define Function23 if you need it, up to the JVM limit. Or you can group arguments into tuples. Or you could just stop pretending that any function takes more than one argument:
没有这样的限制。即使标准库最多只定义了 Function22,你也可以根据需要定义 Function23,直到 JVM 限制。或者您可以将参数分组为元组。或者你可以停止假装任何函数接受多个参数:
a => b => c => d => e => ...
Curried functions can take as many arguments as you want, up to the limit of your stack size.
柯里化函数可以根据需要采用任意数量的参数,最多可达堆栈大小的限制。
回答by Kevin Wright
It's mostly arbitrary, but there aresome underlying limits on the JVM that dictate roughly what the limit needs to be.
这主要是任意的,但JVM有一些潜在的限制,大致规定了限制需要是什么。
The main issue is pattern-matching on case classes. If a case class allowed to be much bigger then the generated pattern-match code could very easily exceed the maximum valid method size. Everything else (Product, Function, Tuple, ...) just follows the 22-parameter limit that was therefore chosen for case classes.
主要问题是案例类的模式匹配。如果允许案例类更大,那么生成的模式匹配代码很容易超过最大有效方法大小。其他所有内容(产品、函数、元组等)都遵循因此为案例类选择的 22 个参数限制。
Also... If you're writing functions/tuples with > 22 parameters then you're probably overdue for a redesign :)
另外...如果您正在编写具有 > 22 个参数的函数/元组,那么您可能需要重新设计了 :)
回答by Landei
Arbitrary choice. Even though these classes are automatically generated, there must be a limit somewhere.
随意选择。即使这些类是自动生成的,也必须在某处存在限制。
Note that you can have something like "tuples of arbitrary size" by using HLists or similar constructs (see http://jnordenberg.blogspot.com/2008/08/hlist-in-scala.html)
请注意,您可以使用 HLists 或类似的结构来获得类似“任意大小的元组”的内容(请参阅http://jnordenberg.blogspot.com/2008/08/hlist-in-scala.html)
回答by Mario Galic
Limit 22 has been droppedin dotty (Scala 3) by Drop function 22 limit #1758:
极限22已经下降在疯疯癫癫(斯卡拉3)删除功能22限制#1758:
The limits of 22 for the maximal number of parameters of function types and the maximal number of fields in tuple types have been dropped.
Functions can now have an arbitrary number of parameters. Functions beyond
Function22are erased to a new traitscala.FunctionXXLand tuples beyondTuple22are erased to a new traitscala.TupleXXL. Both of these are implemented using arrays.
函数类型的最大参数数和元组类型中的最大字段数的 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)
}
outputs 276. For examples of interplay between arbitrary arity tuples and functions see Add generalized tupled functions abstraction #6568
输出276。有关任意元组和函数之间相互作用的示例,请参阅添加通用元组函数抽象 #6568

