There is no Scala string
When you look into
Predef.scala you will find the following definition:
type String = java.lang.String
This means that
String is just a type synonym for
java.lang.String. There is no difference.
In Scala there is the so called "pimp my library" pattern (the name seems to have changed in the meantime, but this is the original name). This pattern lets you add additional behavior to an existing type (without changing the type). It is implemented using implicit conversions. This means during compile time, when necessary the compiler will inject a function that changes the pre existing type to a new type. This new type can then provide the new behavior, usually some convenience methods. When using so called value classes, this conversion comes with zero runtime costs.
Pimp my string: StringOps
Predef.scala provides such an implicit conversion for strings:
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)
This function converts an object of type
String (i.e. a Java string) to an object of type
StringOps provides several convenience functions especially for Strings (e.g.
stripMargin) and some functions that make a String behave like a sequence of Chars (e.g.
Whenever you access one of these functions on a Java string, the compiler will insert a function call for
augmentString to convert your plain Java string to a Scala StringOps.
Why is a string a sequence of Chars?
Scala has a very powerful API, called a monadic API. This API let you filter, transform and combine many different types with a common structure. So you can use the same API to access e.g. objects of type
List as well as objects of type
Future. It is very convenient to give this API also to strings.
With JSR 335, there will also be a monadic API in Java. But it will take some time, until plain Java stings will also get a monadic API out of the box.
Performance considerations: The way back is expensive
While converting a string to a sequence of characters has no runtime costs, the opposite way can be more expensive. When you have a sequence of chars and want it to convert to a string, there is usually no implicit conversion for this. You have to do it explicit, using
There are some special optimizations for
StringOps, i.e. for Strings considered as sequences of characters. They are indeed automatically converted back to a string. The methods in
StringOps are directly returning a string as their result when possible, e.g.
def map[B](f: (A) ⇒ B): String[B]
def filter(p: (Char) ⇒ Boolean): String
For these functions it is usually as cheap to create a string directly as it would be to create an intermediate sequence as their result.
Scala will automatically convert between sequences of characters and strings when there are no additional costs. When it is costly, you will have to make an explicit conversion. In all usual use cases you don't have to worry about this, because Scala will automatically do the right thing. In all other cases it might be useful to know, what happens behind the scenes.