简体   繁体   中英

Scala Trait Mixin order

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

In the above code, price() method from AddIt trait executes first (from print statement).But shouldn't the value be 6 10 14 18 ? Why the values are doubled before adding?

The result makes sense:

  1. printIt calls AddIt.price
  2. AddIt.price calls DoubleIt.price , and then adds 2 to each one
  3. DoubleIt.price calls Numbers.price , and then dubles each one, returning List(2,6,10,14)
  4. This means that AddIt.price returns List(2+2, 6+2, 10+2, 14+2) , which is indeed the printed result

The key here is understanding that indeed AddIt.price starts before DoubleIt.price , but it uses the result of DoubleIt.price to create the return value, before the addition.

Your traits are stacked in the order that you declare them:

AddIt

DoubleIt

Numbers

When you run printIt, you're doing it on an AddIt, resulting in the following call chain:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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