当类型类不在专用源文件中时,为什么Scala不能在伴随对象中隐式定义我的类型类实例?

Jim*_*imN 1 scala implicit typeclass companion-object

请参阅下面的源代码.所有源代码都在同一个包中定义.当我定义一个源文件中的所有代码ShowMain.scala,我得到一个编译错误,但是当object ShowMain在被定义ShowMain.scalatrait Showobject Show中定义Show.scala,也没有编译错误.

我的问题: 这是什么原因?我遇到了什么语言规则?

示例代码:

object ShowMain {

  def main(args: Array[String]): Unit = {
    output("hello")
  }

  def output[A](a: A)(implicit show: Show[A]) =
    println(show.show(a))

}

trait Show[-A] {
  def show(a: A): String
}

object Show {

  implicit object StringShow extends Show[String] {
    def show(s: String) = s"[String: $s]"
  }

}
Run Code Online (Sandbox Code Playgroud)

编译错误:

(ScalaIDE/Scala 2.11.2在线包含output("hello"))

Multiple markers at this line
    - not enough arguments for method output: (implicit show: test.typeclasses.show1.Show[String])Unit. Unspecified value 
     parameter show.
    - not enough arguments for method output: (implicit show: test.typeclasses.show1.Show[String])Unit. Unspecified value 
     parameter show.
    - could not find implicit value for parameter show: test.typeclasses.show1.Show[String]
    - could not find implicit value for parameter show: test.typeclasses.show1.Show[String]
Run Code Online (Sandbox Code Playgroud)

som*_*ytt 9

有一个规则,必须在编译单元中先前定义隐式.

因此,将对象Show移动到顶部并进行编译.

或者,

object Show {
  //implicit object StringShow extends Show[String] {
  implicit val x: Show[String] = new Show[String] {
    def show(s: String) = s"[String: $s]"
  }
}
Run Code Online (Sandbox Code Playgroud)

看到关于类型的解释:

/sf/answers/191189981/