At first glance, a Scala String
appears to be just a Java String
. For
instance, when you work in the Scala
Read-Evaluate-Print-Loop (REPL) environment (see
Figure 1-1) and print the
name of a String
literal, the REPL
feedback tells you the type is java.lang.String
:
scala> "Hello, world".getClass.getName
res0: String = java.lang.String
Indeed, a Scala String
is a Java String
,
so you can use all the normal Java string methods. You can create a string
variable, albeit in the Scala way:
val
s
=
"Hello, world"
You can get the length of a string:
s
.
length
// 12
You can concatenate strings:
val
s
=
"Hello"
+
" world"
These are all familiar operations. But because Scala offers the
magic of implicit conversions, String
instances also have access to all the
methods of the StringOps
class, so you
can do many other things with them, such as treating a String
instance as a sequence of characters. As
a result, you can iterate over every character in the string using the
foreach
method:
scala> "hello".foreach(println)
h
e
l
l
o
You can treat a String
as a
sequence of characters in a for
loop:
scala> for (c <- "hello") println(c)
h
e
l
l
o
You can also treat it as a sequence of bytes:
scala
>
s
.
getBytes
.
foreach
(
println
)
104
101
108
108
111
Because there are many methods available on sequential collections,
you can also use other functional methods like filter
:
scala> val result = "hello world".filter(_ != 'l')
result: String = heo word
It’s an oversimplification to say that this functionality comes from
the StringOps
class, but it’s a useful
illusion. The reality is that some of this
functionality comes from StringOps
,
some comes from StringLike
, some from
WrappedString
, and so on. If you dig
into the Scala source code, you’ll see that the rabbit hole goes deep, but
it begins with the implicit conversion from String
to StringOps
in the Predef
object.
Note
When first learning Scala, take a look at the source code for the
Predef
object. It provides nice
examples of many Scala programming features.
Figure 1-2, taken
from the StringOps
class Scaladoc page,
shows the supertypes and type hierarchy for the StringOps
class.
Even though the String
class is
declared as final
in Java, you’ve
seen that Scala somehow adds new functionality to it. This happens
through the power of implicit conversions. Recipe 1.9, demonstrates how to add your own methods
to the String
class using this
technique.
As one more example of how this pattern helps a Scala String
have both string and collection
features, the following code uses the drop
and take
methods that are available on Scala
sequences, along with the capitalize
method from the StringOps
class:
scala> "scala".drop(2).take(2).capitalize
res0: String = Al
In this chapter you’ll see examples like this, and many more.
Get Scala Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.