Skip to content

Instantly share code, notes, and snippets.

@JamesMenetrey
Last active October 9, 2017 22:42
Show Gist options
  • Save JamesMenetrey/693610411f79ae08197323144cb38a7b to your computer and use it in GitHub Desktop.
Save JamesMenetrey/693610411f79ae08197323144cb38a7b to your computer and use it in GitHub Desktop.
Structural types in Scala: IDisposable (.NET) rewritten using duck typing.
package scalaInAction.chapter8ScalableExtensibleComponents
import org.scalatest.{FlatSpec, Matchers}
/**
* Declare the .NET keyword as a singleton.
*/
object using {
/**
* Type alias.
*/
type Disposable = { def dispose(): Unit }
/**
* Defines the method <i>apply</i> that takes a type <i>T</i> that is a structural type (of type <i>Disposable</i>). It is
* narrowed by an upper bound. The <i>code</i> is a function called-by-name.
*/
def apply[T <: Disposable](disposable: T)(code: T => Unit) {
try code(disposable)
finally disposable.dispose()
}
}
case class File(name: String) {
def dispose(): Unit = {} // This method would close the file, obviously... :-)
}
/**
* Structural types is a mechanism that avoids to create traits to segregate general features that are
* transversely available in other traits/classes. It can be easily compared to duck typing.
*
* @see <a href="https://stackoverflow.com/q/5588208/2780334">What are the performance and maintenance considerations of using Scala's structural types ?</a>
* @see <a href="https://stackoverflow.com/q/4543228/2780334">What's the difference between => , ()=>, and Unit=></a>
*/
class StructuralTypes extends FlatSpec with Matchers {
/**
* Can be useful for 3rd party libraries, as an alternative to the <i>pimp my library</i> pattern.
*/
"A structural type" can "work like the duck typing mechanism, preventing to create a dedicated trait" in {
val filename = "test.txt"
using (File(filename)) { file =>
file.name should be (filename)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment