Struct Embedding in Scala

Scala supports trait mixing, which is similar to struct embedding in other languages. This allows for a more seamless composition of types.

import scala.language.implicitConversions

// Define a base class
class Base(val num: Int) {
  def describe: String = s"base with num=$num"
}

// A Container class mixes in the Base trait
class Container(override val num: Int, val str: String) extends Base(num)

object StructEmbedding {
  def main(args: Array[String]): Unit = {
    // When creating instances, we initialize all fields
    val co = new Container(1, "some name")

    // We can access the base's fields directly on co
    println(s"co={num: ${co.num}, str: ${co.str}}")

    // We can also access methods from the base class
    println("describe: " + co.describe)

    // Define a trait for describing
    trait Describer {
      def describe: String
    }

    // Container implicitly implements the Describer trait
    // because it extends Base which has the describe method
    val d: Describer = co
    println("describer: " + d.describe)
  }
}

When you run this Scala program, you’ll see the following output:

$ scala StructEmbedding.scala
co={num: 1, str: some name}
describe: base with num=1
describer: base with num=1

In this Scala example, we’ve used inheritance and trait mixing to achieve a similar effect to struct embedding. The Container class extends Base, which allows it to inherit the num field and the describe method.

Scala’s trait system is powerful and flexible, allowing for multiple inheritance of behavior. In this case, we defined a Describer trait, which Container implicitly implements because it extends Base which has the describe method.

This demonstrates how Scala’s type system can be used to create composable and reusable components, similar to struct embedding in other languages.