【问题标题】:Using constructor where function expected在预期函数的地方使用构造函数
【发布时间】:2011-10-08 07:53:13
【问题描述】:

有两个以Int 为参数的简单类:

case class Foo(i: Int)
     class Bar(j: Int)

我可以说:

List(1,2,3) map Foo

效果很好,相当于更详细一点:

List(1,2,3) map {Foo(_)}

但是Bar(因为它不是案例类?)不能在同一个构造中使用:

List(1,2,3) map Bar

  error: not found: value Bar
          List(1,2,3) map Bar
                          ^

是否有一些特殊的语法可以引用任何构造函数并利用 eta 扩展?与Foo 相比,List(1,2,3) map {new Bar(_)} 似乎更冗长。

【问题讨论】:

  • Eta 扩展是发生在方法上的事情。请注意,构造函数不是方法。
  • @DanielC.Sobral 究竟什么是构造函数?
  • @AshkanKh.Nazary 构造函数是一系列指令,用于初始化新分配的对象。
  • @DanielC.Sobral 那不是方法或函数吗?您不能显式调用它或传递它或对其应用 eta 扩展以将其转换为函数?
  • @AshkanKh.Nazary 不,你不能。例如,试试new String _。它在字节码级别也有所不同,方法和构造函数之间的 JVM 期望也存在各种差异。

标签: scala constructor higher-order-functions


【解决方案1】:

它适用于前一种情况,因为案例类的伴生对象扩展了适当的FunctionN 特征。 (在您的示例中为object Foo extends (Int => Foo)。)对于非案例类,您可以手动执行此操作:

scala> class Bar(i: Int)
defined class Bar

scala> class Bar(i: Int); object Bar extends (Int => Bar) { def apply(i: Int) = new Bar(i) }
defined class Bar
defined module Bar

scala> List(2, 3) map Bar
res17: List[Bar] = List(Bar@1f99e90, Bar@1191056)

IMO 最好使用 new Bar(_),因为这个额外的样板文件可能不值得实现一点简洁。

【讨论】:

  • 有趣,不知道案例类扩展了FunctionN。我记得一个 SO 答案,其中列出了案例类的所有自动功能,但不记得提到的那个问题。
  • 案例类没有。它们的伴生物体会。
【解决方案2】:

由于Foo 是一个案例类,因此还有一个名为Foo 的伴随对象,它实现了Function1 接口(如果构造函数采用三个参数,它将是Function3 接口)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2012-10-27
    • 2012-11-10
    • 1970-01-01
    • 2021-01-08
    • 2019-01-06
    相关资源
    最近更新 更多