Scala Tutorial - Learn How To Create Implicit Function
Overview
In this tutorial, we will learn how to create implicit function which will allow you to provide extension methods or functions to pretty much any type or class.
As the name implies, Scala was designed from the ground up to be extensible. Feel free to review the Scala Features tutorial which outlines the use of implicit as one of the features which Scala provides to allow you to easily add extension methods or functions to any type or class.
To continue with our Donut Store examples from the previous tutorials, we will extend the String class such that it will have an isFavoriteDonut() function.
Steps
1. How to create a wrapper String class which will extend the String type
Let us create a simple wrapper class called DonutString which will take the String type as its parameter and then provide an isFavoriteDonut() function.
println("Step 1: How to create a wrapper String class which will extend the String type")
class DonutString(s: String) {
def isFavoriteDonut: Boolean = s == "Glazed Donut"
}
NOTE:
- If you are coming from a Java or .NET programming background, you would perhaps be pleasantly surprised that in Scala you can simply compare two Strings using == as opposed to using equals() method.
2. How to create an implicit function to convert a String to the wrapper String class
It is a good practice to encapsulate your implicit functions or conversions into a singleton using object. You can also make use of package object which we will see in upcoming tutorials.
As such, let us define an implicit function named stringToDonutString which will take the String type as its parameter and wire it through a new instance of the wrapper String class named DonutString from Step 1.
println("\nStep 2: How to create an implicit function to convert a String to the wrapper String class")
object DonutConverstions {
implicit def stringToDonutString(s: String) = new DonutString(s)
}
NOTE:
- Defining an implicit function is similar to defining any other functions except that we've prefixed the function signature using the implicit keyword.
3. How to import the String conversion so that it is in scope
In order to use the implicit String function which will convert a String type into a DonutString type, you will have to have the implicit function from Step 2 in scope. This can be achieved using the import keyword as shown below:
println("\nStep 3: How to import the String conversion so that it is in scope")
import DonutConverstions._
NOTE:
- As part of the import expression, we are using the wildcard operator _ which will import any values or implicit functions.
4. How to create String values
Let us create two immutable values of type String, one for Glazed Donut and the other for Vanilla Donut.
println("\nStep 4: How to create String values")
val glazedDonut = "Glazed Donut"
val vanillaDonut = "Vanilla Donut"
NOTE:
- By now, you should be familiar with declaring variables and immutable values.
- Feel free to review the tutorial on declaring variables.
5. How to access the custom String function called isFavaoriteDonut
How would you access the isFavoriteDonut() function from Step 1? Simple - just call it on the Glazed Donut or Vanilla Donut String values.
println("\nStep 5: How to access the custom String function called isFavaoriteDonut")
println(s"Is Glazed Donut my favorite Donut = ${glazedDonut.isFavoriteDonut}")
println(s"Is Vanilla Donut my favorite Donut = ${vanillaDonut.isFavoriteDonut}")
You should see the following output when you run your Scala application in IntelliJ:
Step 5: How to access the custom String function called isFavaoriteDonut
Is Glazed Donut my favorite Donut = true
Is Vanilla Donut my favorite Donut = false
NOTE:
- The custom isFavoriteDonut() function looks built-into the String class.
- However, we did not have to manually modify the source code of the String class.
- Instead, we've used the secret powers of Scala's implicit function to extend the String class.
Summary
In this tutorial, we went over the following:
- How to create a wrapper String class which will extend the String type
- How to create an implicit function to convert a String to the wrapper String class
- How to import the String conversion so that it is in scope
- How to create String immutable values
- How to access the custom String function called isFavoriteDonut()
Tip
- It is a good practice to encapsulate your implicit functions and values into an Object or a Package Object.
- The Scala Predef class makes use of implicit function to provide ready made conversions such as Java from/to Scala.
Source Code
The source code is available on the allaboutscala GitHub repository.
What's Next
In the next tutorial, I will show you how to define functions which is typed such that you can provide the parameter types when calling the function.