scala中trait和abstract class在隱式轉換中的區別

說半天還不如看一點代碼更清楚問題之所在:ide

object ImplicitObject3 {
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends SubTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends SubTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}
trait Template[A] {
  def add(x:A,y:A):A
}
trait SubTemplate[A] extends Template[A] {
  def unit:A
}

編譯正確,執行時:在類加載器加載時出現異常。可是將二個trait放在object ImplicitObject3中,無論是放在main的前面仍是後面都執行OK:scala

object ImplicitObject3 {
trait Template[A] {
  def add(x:A,y:A):A
}
trait SubTemplate[A] extends Template[A] {
  def unit:A
}
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends SubTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends SubTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}

若是將二個trait改成abstract class形式,定義在object ImplicitObject3以外執行也OK:調試

object ImplicitObject3 {
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends SubTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends SubTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}
abstract class Template[A] {
  def add(x:A,y:A):A
}
abstract class SubTemplate[A] extends Template[A] {
  def unit:A
}

爲何會有這樣的現象,緣由是什麼呢???????????????????????code

當我在object ImplicitObject3外面定義二個trait以外,還在二個trait同級定義了一個繼承自SubTemplate[A]的abstract class類,同時將main中二個implicit object繼承的父改成這個抽象類,則一切都OK了。這種狀況下,實驗OK,其實緣由好理解:繼承

object ImplicitObject3 {
def main(args: Array[String]): Unit = {
    def sum[A](xs:List[A])(implicit st:SubTemplate[A]):A = {
      if(xs.isEmpty) st.unit
      else st.add(xs.head,sum(xs.tail))
    }
    
    implicit object SubTemplateImplicitIntValue extends abstractTemplate[Int] {
      override def unit: Int = 0

      override def add(x: Int, y: Int): Int = x + y
    }
    implicit object SubTemplateImplicitStringVlaue extends abstractTemplate[String] {
      override def unit: String = ""

      override def add(x: String, y: String): String = x + y
    }
    println(sum(List(1,2,3,4,5)))
    println(sum(List("abc","efg","hijk")))
  }
}
trait Template[A] {
  def add(x:A,y:A):A
}
trait SubTemplate[A] extends Template[A] {
  def unit:A
}
abstract class abstractTemplate[A] extends SubTemplate[A]

有一次無心中,我將二個trait放在另外一個單獨的scala文件中,而後我編譯工程而後調試,不成功。鬼使神差地在main的最開頭import SubTemplate一次,竟然成功了。我將磁盤上全部class文件都刪除了再編譯工程卻又不成功。而後再去掉import,單獨編譯那個scala文件,再編譯工程卻又成功執行代碼了。總結來看:這是因爲IDEA形成class文件與源代碼不一致的緣由ci

相關文章
相關標籤/搜索