简体   繁体   English

为什么Scala函数接受函数参数的大小写类类型?

[英]why does Scala function accepts case class type for a function argument?

Consider the code block. 考虑代码块。

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)

Why does Dept can be passed as a Funtion1 type? 为什么Dept可以作为Funtion1类型传递? Is it that, Scala does not checks for the type before resolving the arguments. 就是这样,Scala不会在解析参数之前检查类型。

Consider other snippet 考虑其他片段

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

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

Whereas in the above code scala gives a match error, as expected. 而在上面的代码中,scala给出了匹配错误,正如预期的那样。

The companion object of a case class extends FunctionX[T1, T2, <CaseClass>] so that you can use it to construct instances of the case class. 案例类的伴随对象扩展了FunctionX[T1, T2, <CaseClass>]因此您可以使用它来构造案例类的实例。

So, for example, if you have a case class 因此,例如,如果您有案例类

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

the compiler will generate a companion object 编译器将生成一个伴随对象

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
}

This allows you to construct an instance of Foo like this: 这使您可以像下面这样构造Foo的实例:

Foo(42, "Hello")

instead of 代替

new Foo(42, "Hello")

So, to conclude: the reason, why you can pass the Dept companion object as a function is because it is a function. 因此,可以得出结论:之所以可以将Dept随行对象作为函数传递,是因为它一个函数。

Dept is not a "case class type", it's the companion object for the case class. Dept不是“案例类类型”,它是案例类的伴侣object It extends Function1 (and has .apply method, that's part of the interface), so you can use it wherever a function is expected. 它扩展了Function1 (并具有.apply方法,这是接口的一部分),因此您可以在需要函数的任何地方使用它。

The second snipped fails because { x => Dept(x) } is it's own anonymous function, not Dept object. 第二个失败的原因是{ x => Dept(x) }是它自己的匿名函数,而不是Dept对象。

It has a lot of sense, because if you just give as paramenter Dept it will behave ass a function that takes a String as parameter, and return an instance of the class Dept, meaning a Dept object (It is like give the new or apply function as parameter), look that the following code is valid also: 这很有道理,因为如果您只是给Dept做为paramenter,它将表现为一个以String为参数的ass函数,并返回Dept类的实例,这意味着一个Dept对象(就像给new或apply函数作为参数),请注意以下代码也有效:

val c: Dept.type = Dept

val dep = c("Name1")

dep

res1: Dept = Dept(Name1) res1:部门=部门(Name1)

dep.evaluate

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM