当您创建案例类时,编译器会创建一个相应的伴随对象,其中包含一些案例类的好处:与主构造函数匹配的 apply
工厂方法、equals
、hashCode
和复制
。
有点奇怪的是,这个生成的对象扩展了 FunctionN。
scala> case class A(a: Int)
defined class A
scala> A: (Int => A)
res0: (Int) => A = <function1>
只有在以下情况下才会出现这种情况:
- 没有手动定义的伴生对象
- 仅有一个参数列表
- 没有类型参数
- 案例类不是抽象的。
似乎这是大约两年前添加的。最新的版本是 此处。
有谁使用过这个,或者知道为什么添加它?它使用静态转发器方法稍微增加了生成的字节码的大小,并显示在伴随对象的 #toString()
方法中:
scala> case class A()
defined class A
scala> A.toString
res12: java.lang.String = <function0>
UPDATE
手动创建的对象单个 apply
方法不会自动被视为 FunctionN
:
object HasApply {
def apply(a: Int) = 1
}
val i = HasApply(1)
// fails
// HasApply: (Int => Int)
When you create a case class, the compiler creates a corresponding companion object with a few of the case class goodies: an apply
factory method matching the primary constructor, equals
, hashCode
, and copy
.
Somewhat oddly, this generated object extends FunctionN.
scala> case class A(a: Int)
defined class A
scala> A: (Int => A)
res0: (Int) => A = <function1>
This is only the case if:
- There is no manually defined companion object
- There is exactly one parameter list
- There are no type arguments
- The case class isn't abstract.
Seems like this was added about two years ago. The latest incarnation is here.
Does anyone use this, or know why it was added? It increases the size of the generated bytecode a little with static forwarder methods, and shows up in the #toString()
method of the companion objects:
scala> case class A()
defined class A
scala> A.toString
res12: java.lang.String = <function0>
UPDATE
Manually created objects with a single apply
method are not automatically considered as FunctionN
:
object HasApply {
def apply(a: Int) = 1
}
val i = HasApply(1)
// fails
// HasApply: (Int => Int)
发布评论
评论(4)
案例类伴生对象之所以实现FunctionN,是因为之前案例类生成的是类和工厂方法,而不是伴生对象。当我们向 Scala 添加提取器时,将工厂方法转变为具有 apply 和 unapp 方法的完整伴生对象更有意义。但是,由于工厂方法确实符合 FunctionN,因此伴随对象也需要符合。
[编辑] 也就是说,让伴生对象显示为它们自己的名称而不是“函数”是有意义的
The reason why case class companion objects implement FunctionN is that before, case classes generated a class and a factory method, not a companion object. When we added extractors to Scala it made more sense to turn the factory method into a full companion object with apply and unapply methods. But then, since the factory method did conform to FunctionN, the companion object needed to conform, too.
[Edit] That said, it would make sense to have companion objects show as their own name, not as "function"
好吧,考虑到 Scala 中的
target.apply(a1, a2, a3 ... aN)
:target(a1, a2, a3 ... aN)
来加糖>FunctionN
实现的方法,伴生对象:
确实是:
所以添加对我来说似乎很自然(我不确定为什么它看起来“奇怪”)对你来说?)。至于它是否实际上添加了任何东西;好吧,那是给比我聪明的人的!
Well, given that
target.apply(a1, a2, a3 ... aN)
in Scala:target(a1, a2, a3 ... aN)
FunctionN
it seems natural that a companion object:
is really:
So the addition seems to be natural to me (I'm not sure why it seems "odd" to you?). As to whether it actually added anything; well, that is for someone smarter than me!
除了 oxbow_lakes 关于其自然性的回复之外,将构造函数用作一等函数通常很有用,特别是与 Scala 集合高阶函数结合使用。对于(一个简单的)例子,
Aside from oxbow_lakes's reply about the naturalness of it, it can often be useful to have constructors available as first-class functions, particularly in conjunction with Scala collections higher-order functions. For (a trivial) example,