Scala Trait Mixin订单

时间:2016-09-22 13:07:20

标签: scala

object sandbox {

  class Numbers {
    def price() : List[Int] = List(1,3,5,7)
    def printIt(): Unit = {
      price.foreach(x => print(x+ " ") )
    }
  }

  trait DoubleIt extends Numbers {
    override def price() : List[Int] ={
      println("doubling")
      super.price.map(x => x*2)
    }
  }

  trait AddIt extends Numbers {
    override def price() : List[Int] = {
      println("adding")
      super.price.map( x => x+2)
    }
  }

  def main(args :Array[String]): Unit = {
    val obj = new Numbers with DoubleIt with AddIt
    obj.printIt() 
  }

}
//output :
adding
doubling
4 8 12 16

在上面的代码中,price() trait中的AddIt方法首先执行(来自print语句)。但是,值不应该是6 10 14 18吗?添加之前为什么值加倍?

2 个答案:

答案 0 :(得分:5)

结果很有意义:

  1. printIt来电AddIt.price
  2. AddIt.price调用DoubleIt.price然后每个添加2
  3. DoubleIt.price调用Numbers.price,然后逐个调用,返回List(2,6,10,14)
  4. 这意味着AddIt.price会返回List(2+2, 6+2, 10+2, 14+2),这确实是打印结果
  5. 这里的关键是理解AddIt.price DoubleIt.price之前开始,但它使用DoubleIt.price的结果来创建返回值添加之前。

答案 1 :(得分:4)

您的特征按照您声明的顺序堆叠:

ADDIT

DoubleIt

编号

当您运行printIt时,您在AddIt上执行此操作,从而产生以下调用链:

AddIt.printIt
AddIt.printIt.price       //here you get to print "adding"
AddIt.price.super.price   //calls DoubleIt's price
DoubleIt.price            //here you get to print "doubling"
DoubleIt.super.price      //calls Number's price
Numbers.price             //returns List(1, 3, 5, 7)
DoubleIt.super.price.map  //doubles your list input
AddIt.super.price.map     //adds 2 to the result
AddIt.printIt.foreach     //prints the final result