为什么要编译和发生了什么?

时间:2014-04-02 06:07:52

标签: scala

我正在编写一个包装类,它将大多数调用传递给根对象,并且我意外地保留了完整的定义(带参数名称x等),如下所示。令我惊讶的是,它汇编了。那么这里发生了什么?这类似于分配给root.p_吗?我觉得很奇怪,我可以留下这个名字" x"在分配中。另外,传递包装调用的最佳(最快)方式是什么?或者它可能没有区别?

trait A {
  def p(x:Int) = println("A"+123)
}

case class B(root:A) {

  def p(x: Int): Unit = root.p(x:Int)  // WHAT HAPPENED HERE?
}

object Test extends App {
   val temp = new A{}
  val b = B(temp)
  b.p(123)
}

2 个答案:

答案 0 :(得分:2)

类型归属会发生什么,而且这里并不多。

代码就像你写过

一样
def p(x: Int): Unit = root.p(x)
按照你的意图。当您在调用中写入x: Int时(不在声明中,它具有完全不同的含义)或更一般地expr: Type,它具有与expr相同的值,但它告诉编译器检查expr是否为给定类型(这是一个检查是一个编译类型,一种是upcast,而不是运行时检查,如asInstanceOf[...]),并且它已经具有该类型。这里,x确实是一个Int,并且它已被编译器视为Int,因此ascription不会改变任何内容。

除了在代码中的某处记录非显而易见的类型之外,还可以使用类型ascription在重载方法之间进行选择:

def f(a: Any) ...
def f(i: Int) ...

f(3) // calls f(i: Int)
f(3: Any) // calls f(a: Any)

请注意,在第二次调用中,使用ascription,编译器知道3类型为Any,不如Int精确,但仍然为真。否则,这将是一个错误,这不是演员。但是归属使它调用f的另一个版本。

您可以查看该答案以获取更多详细信息:https://stackoverflow.com/a/2087356/754787

答案 1 :(得分:0)

您是否将B.p的实施委托给A.p

除了root.p(x:Int)之外,我没有看到任何异常情况,您可以按root.p(x)保存输入内容。

trait是一种代码混合方式,我认为最简单的方法是:

trait A {
  def p(x: Int) = println("A" + x)
}

case class B extends AnyRef with A

val b = B() 
b.p(123)