为什么Scala函数接受函数参数的case类类型?

时间:2017-12-26 17:58:28

标签: scala functional-programming

考虑代码块。

class Evaluation {
  def evaluate= {
    println("Charlie...")
  }
}
case class Dept(name:String) extends Evaluation

def depEval(name:String,f:(String) => Evaluation) ={
  println(name)
  f(name).evaluate
}
depEval("abc", Dept)

为什么Dept可以作为Funtion1类型传递?是这样,Scala在解析参数之前不会检查类型。

考虑其他代码段

def matchingCase(f: String => Evaluation)= {
  println(f.toString())
  f match {
    case Dept => println("function type matched")
  }
}

matchingCase((x: String)=> Dept(x))

然而在上面的代码中,scala给出了匹配错误,正如预期的那样。

3 个答案:

答案 0 :(得分:5)

案例类的伴随对象扩展FunctionX[T1, T2, <CaseClass>],以便您可以使用它来构造案例类的实例。

因此,例如,如果你有一个案例类

case class Foo(i: Int, s: String)

编译器将生成一个伴随对象

object Foo extends (Int, String) ⇒ Foo with Product2[Int, String] {
  def apply(i: Int, s: String) = new Foo(i, s)

  // and some other stuff such as equals, hashCode, copy
}

这允许您像这样构建Foo的实例:

Foo(42, "Hello")

而不是

new Foo(42, "Hello")

因此,总结一下:为什么你可以将Dept伴侣对象作为函数传递的原因是因为 是一个函数。

答案 1 :(得分:3)

Dept不是&#34;案例类类型&#34;,它是案例类的伴随object。它扩展了Function1(并且具有.apply方法,这是界面的一部分),因此您可以在任何需要函数的地方使用它。

第二个剪辑失败,因为{ x => Dept(x) }是它自己的匿名函数,而不是Dept对象。

答案 2 :(得分:0)

它有很多意义,因为如果你只是作为参数Dept,它将表现为一个函数,它接受一个String作为参数,并返回一个类Dept的实例,意思是一个Dept对象(它就像给出new或应用函数作为参数一样),看下面的代码也是有效的:

val c: Dept.type = Dept

val dep = c("Name1")

dep

res1:Dept = Dept(Name1)

dep.evaluate

...查理 res2:单位=()