vishvAs vAsuki
vishvAs vAsuki

Reputation: 3137

List of String implicit conversions like +=

Consider the following snippet. += is not a member of java.lang.String, so I guess there is some sort of Implicit conversion going on. How do I find a list of such predefined implicit conversions acting on String?

scala> var x = "asdf"
x: java.lang.String = asdf

scala> x += x

scala> x
res2: java.lang.String = asdfasdf

Upvotes: 4

Views: 680

Answers (4)

Kipton Barros
Kipton Barros

Reputation: 21112

Not specific to String, but the Scala REPL has a neat feature to see all the implicits in scope:

scala> :implicits
No implicits have been imported other than those in Predef.

scala> :implicits -v
/* 96 implicit members imported from scala.Predef */
  /* 66 inherited from scala.Predef */
  implicit def Double2double(x: jl.Double): Double
  implicit def byte2double(x: Byte): Double
  implicit def char2double(x: Char): Double
  ...

  /* 30 inherited from scala.LowPriorityImplicits */
  implicit def genericWrapArray[T](xs: Array[T]): mutable.WrappedArray[T]
  implicit def wrapBooleanArray(xs: Array[Boolean]): mutable.WrappedArray[Boolean]
  implicit def wrapByteArray(xs: Array[Byte]): mutable.WrappedArray[Byte]
  ...

It's also worth noting that implicits don't have to be in scope to be applied. For example, we can define an implicit conversion in a companion object,

case class Foo(s: String)
object Foo { implicit def string2Foo(s: String) = Foo(s.reverse) }

and then apply it, even though its not in scope,

scala> val f: Foo = "hello"
f: Foo = Foo(olleh)

The Foo companion object is searched for implicits because the target type is Foo. For more info, see Daniel Sobral's answer to: Where does Scala look for implicits?

Upvotes: 4

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297265

You picked a particularly bad example. += is, in a sense, part of String. See this comment on the Javadoc for java.lang.String:

The Java language provides special support for the string concatenation operator ( + ), and for conversion of other objects to strings.

You'll have to look up Java language specification to find more information about it (15.18.1). But, then again, Scala is not Java, so + is also part of the Scala language specification (12.3.1).

So far I have spoken of +, not +=. However, Scala has a special syntactic sugar for assignment. As described in section 6.12.4, except for <=, >=, != and operators starting with an =, any operator symbol (see "operator characters" in chapter 1) that ends in an equal sign will be reinterpreted if it does not exist as a method. Specifically,

x += 1

will be reinterpreted as

x = x + 1

That will happen regardless of whether x is a var, so one might occasionally see an error message "reassignment to val".

So, as you can see, += is really part of String, through an exception in Java specification that was replicated in Scala specification, plus a bit of syntactic sugar.

Which doesn't mean there aren't methods not in java.lang.String that can be used with it through implicit conversions. I'll leave that to the other answers, however. If I were you, I'd change the method in the question, to make it correct. Besides, += is unsearchable in Stack Overflow.

Upvotes: 13

tenshi
tenshi

Reputation: 26576

You need to look in scala.Predef - all implicits that are defined there would be always in scope (so you don't need to import them).

If you look in it's source code, you will find this section:

// Strings and CharSequences ------------

...

implicit def augmentString(x: String): StringOps = new StringOps(x)
implicit def unaugmentString(x: StringOps): String = x.repr

...

Upvotes: 8

agilesteel
agilesteel

Reputation: 16859

StringOps defines implicit conversions for String. It gets imported into the scope in scala.Predef along with other useful things.

Upvotes: 4

Related Questions