Last active
October 9, 2017 22:42
-
-
Save JamesMenetrey/693610411f79ae08197323144cb38a7b to your computer and use it in GitHub Desktop.
Structural types in Scala: IDisposable (.NET) rewritten using duck typing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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