String interpolation in Scala 2.10 and newer (String variable substitution)

Scala string FAQ: How do I embed variables in strings in Scala?

A lot of nice new features were added to the Scala language in version 2.10, but a simple feature that makes me happy is string interpolation. This lets Scala developers embed variables inside strings just like you can do in other languages like Perl, PHP, and Ruby -- but perhaps in an even more powerful way. (I say "perhaps" because I haven't used those other languages recently.)

Back to top

Solution

To use basic string interpolation in Scala, precede your string with the letter s and include your variables inside the string, with each variable name preceded by a $ character.

This is shown in the println statement in the following example:

scala> val name = "Fred"
name: String = Fred

scala> val age = 33
age: Int = 33

scala> val weight = 200.00
weight: Double = 200.0

scala> println(s"$name is $age years old, and weighs $weight pounds.")
Fred is 33 years old, and weighs 200.0 pounds.

According to the official Scala string interpolation documentation, when you precede your string with the letter s, you’re creating a processed string literal. This example uses the “s string interpolator,” which lets you embed variables inside a string, where they’re replaced by their values. As stated in the documentation, “Prepending s to any string literal allows the usage of variables directly in the string.”

Back to top

Using expressions in Scala string literals

In addition to putting variables inside strings, you can include expressions inside a string by placing the expression inside curly braces. According to the official string interpolation documentation, “Any arbitrary expression can be embedded in ${}.”

In the following example, the value 1 is added to the variable age inside the string:

scala> println(s"Age next year: ${age + 1}")
Age next year: 34

This example shows that you can use an equality expression inside the curly braces:

scala> println(s"You are 33 years old: ${age == 33}")
You are 33 years old: true

You’ll also need to use curly braces when printing object fields. The following example shows the correct approach:

scala> case class Student(name: String, score: Int)
defined class Student

scala> val hannah = Student("Hannah", 95)
hannah: Student = Student(Hannah,95)

scala> println(s"${hannah.name} has a score of ${hannah.score}")
Hannah has a score of 95

Attempting to print the values of the object fields without wrapping them in curly braces results in the wrong information being printed out:

// error: this is intentionally wrong
scala> println(s"$hannah.name has a score of $hannah.score")
Student(Hannah,95).name has a score of Student(Hannah,95).score

Because $hannah.name wasn’t wrapped in curly braces, the wrong information was printed; in this case, the toString output of the hannah variable.

Back to top

‘s’ is a method

The s that’s placed before each string literal is actually a method. Though this seems slightly less convenient than just putting variables inside of strings, there are at least two benefits to this approach:

  • Scala provides other off-the-shelf interpolation functions to give you more power.
  • You can define your own string interpolation functions.

To see why this is a good thing, let’s look at another string interpolation function.

Back to top

The ‘f’ string interpolator (printf formatting)

In the example in the Solution, the weight was printed as 200.0. This is okay, but what can you do if you want to add more decimal places to the weight, or remove them entirely?

This simple desire leads to the “f string interpolator,” which lets you use printf style formatting specifiers inside strings. The following examples show how to print the weight, first with two decimal places:

scala> println(f"$name is $age years old, and weighs $weight%.2f pounds.")
Fred is 33 years old, and weighs 200.00 pounds.

and then with no decimal places:

scala> println(f"$name is $age years old, and weighs $weight%.0f pounds.")
Fred is 33 years old, and weighs 200 pounds.

As demonstrated, to use this approach, just follow these steps:

  1. Precede your string with the letter f.
  2. Use printf style formatting specifiers immediately after your variables.

The most common printf format specifiers are shown in the table in the Discussion.

Though these examples used the println method, it’s important to note that you can use string interpolation in other ways. For instance, you can assign the result of a variable substitution to a new variable, similar to calling sprintf in other languages:

scala> val out = f"$name, you weigh $weight%.0f pounds."
out: String = Fred, you weigh 200 pounds.
Back to top

The ‘raw’ interpolator

In addition to the s and f string interpolators, Scala 2.10 includes another interpolator named raw. The raw interpolator “performs no escaping of literals within the string.”

The following example shows how raw compares to the s interpolator:

scala> s"foo\nbar"
res0: String =
foo
bar

scala> raw"foo\nbar"
res1: String = foo\nbar

The raw interpolator is useful when you want to avoid having a sequence of characters like \n turn into a newline character.

Back to top

Create your own interpolator

In addition to the s, f, and raw interpolators that are built into Scala 2.10, you can define your own interpolators. See the official Scala String Interpolation documentation for an example of how to create your own interpolator.

Note: String interpolation does not work with pattern-matching statements in Scala 2.10. This feature is planned for inclusion in Scala 2.11.

Back to top

Discussion

Prior to version 2.10, Scala didn’t include the string interpolation functionality just described. If you need to use a release prior to Scala 2.10 for some reason, the solution is to call the format method on a string, as shown in the following examples:

scala> val name = "Fred"
name: java.lang.String = Fred

scala> val age = 33
age: Int = 33

scala> val s = "%s is %d years old".format(name, age)
s: String = Fred is 33 years old

scala> println("%s is %d years old".format(name, age))
Fred is 33 years old

Just as with the string interpolation capability shown in the Solution, you can use this approach anywhere you want to format a string, such as a toString method:

override def toString: String = "%s %s, age %d".format(firstName, lastName, age)

With either of these approaches, you can format your variables using all the usual printf specifiers. The most common format specifiers are shown here:

Format specifier   Description
----------------   ---------------------------------
      %c           Character
      %d           Decimal number (integer, base 10)
      %e           Exponential floating-point number
      %f           Floating-point number
      %i           Integer (base 10)
      %o           Octal number (base 8)
      %s           A string of characters
      %u           Unsigned decimal (integer) number
      %x           Hexadecimal number (base 16)
      %%           Print a “percent” character
      \%           Print a “percent” character
Back to top

See Also

Back to top

The Scala Cookbook

This tutorial is sponsored by the Scala Cookbook, which I wrote for O’Reilly:

You can find the Scala Cookbook at these locations:

Back to top

Add new comment

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.