开发者

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?

sca开发者_JAVA百科la> var x = "asdf"
x: java.lang.String = asdf

scala> x += x

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


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.


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

...


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


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜