Structural types in Scala provide a powerful mechanism for defining types based on structure rather than inheritance. They allow for flexible code design and enable duck typing-like behavior within Scala's static type system.
Structural types define a type by specifying the structure (methods and fields) that an object must have, rather than its class hierarchy. This approach is sometimes called "duck typing" in dynamic languages.
To define a structural type in Scala, use the following syntax:
type StructuralType = { def methodName: ReturnType }
Here's a practical example:
type Closeable = { def close(): Unit }
def closeResource(resource: Closeable): Unit = {
resource.close()
}
In this example, Closeable
is a structural type that requires objects to have a close()
method returning Unit
.
Here's a more complex example demonstrating the power of structural types:
def processData[T <: { def getData(): String; def process(data: String): Int }](obj: T): Int = {
val data = obj.getData()
obj.process(data)
}
class DataProcessor {
def getData(): String = "Some data"
def process(data: String): Int = data.length
}
val result = processData(new DataProcessor())
println(result) // Outputs: 9
In this example, processData
accepts any type that has both getData()
and process()
methods, regardless of its class hierarchy.
To deepen your understanding of Scala's type system, explore these related topics:
Structural types in Scala offer a unique approach to type definition, providing flexibility and power to your code design. While they should be used judiciously due to performance considerations, they can be invaluable in certain scenarios, especially when working with diverse object types or creating flexible APIs.