【问题标题】:why case class can be used as a function in the argument为什么case类可以用作参数中的函数
【发布时间】:2014-10-14 16:50:49
【问题描述】:

偶尔,我发现案例类的一个有趣特性。 foo 需要一个将 3 Int 转换为案例类的函数,代码如下所示:

case class Whatever(a: Int, b: Int, c: Int)

def foo(f: (Int, Int, Int) => Whatever) = f(1,2,3).c

foo(Whatever) //compilation fine, scala complier is powerful ...........

如果Whatever是普通类,显然编译会失败。

谁能解释一下为什么可以这样使用case类,我怀疑是工厂应用方法的原因,但我不确定。另外,如果是普通类,是否可以这样作为case类使用。

【问题讨论】:

  • 你的猜测是正确的。这是因为 scala 为案例类创建的 companian 对象

标签: function scala functional-programming case-class


【解决方案1】:

scala 编译器为案例类生成一个伴随对象并实现一些东西(实现 AbstractFunction3、apply、unapply):

javap Whatever\$.class 
Compiled from "Test.scala"
public final class Whatever$ extends scala.runtime.AbstractFunction3<java.lang.Object,   java.lang.Object, java.lang.Object, Whatever> implements scala.Serializable {
  public static final Whatever$ MODULE$;
  public static {};
  public final java.lang.String toString();
  public Whatever apply(int, int, int);
  public scala.Option<scala.Tuple3<java.lang.Object, java.lang.Object, java.lang.Object>> unapply(Whatever);
  public java.lang.Object apply(java.lang.Object, java.lang.Object, java.lang.Object);
}

【讨论】:

    【解决方案2】:

    正如@planetenkiller 提到的,如果您创建一个案例类,编译器会自动生成一个带有几个方法的伴随对象。

    它特别实现了applyunapply,它们允许您执行以下操作:

    val x = Whatever(1,2,3) // is actually Whatever.apply(1,2,3)
    
    x match {
      case Whatever(x,y,z) => // uses Whatever.unapply
        /* ... */
    }
    

    此外,它使用正确数量的参数扩展FunctionN。因此,案例类的伴生对象一个函数。因此,很明显,您可以将其用作函数(即一次,调用站点上没有魔法)。

     val x: Function3[Int, Int, Int, Whatever] = {
       Whatever // compiles, no implicit conversion
     }
    

    【讨论】:

      【解决方案3】:

      感谢@planetenkiller @gzm0 的解释,所以如果我想正常上课也有同样的行为。这是实现。

      class Whatever(a: Int, b: Int, c: Int)
      
      object Whatever extends ((Int, Int, Int) => Whatever) {
      
      
        def apply(a: Int, b: Int, c: Int): Whatever = {
          new Whatever(a, b, c)
        }
      
      }
      
      def foo(f: (Int, Int, Int) => Whatever) = f(1,2,3)
      
      foo(Whatever)
      

      【讨论】:

        猜你喜欢
        • 2019-04-18
        • 2020-10-03
        • 1970-01-01
        • 2021-05-29
        • 1970-01-01
        • 1970-01-01
        • 2021-04-04
        • 1970-01-01
        • 2021-12-25
        相关资源
        最近更新 更多