-->

Why implicitConversions is required for implicit d

2019-02-04 00:58发布

问题:

As far as I understand, implicit conversions can result in potentially hard to understand code, or code suffering from other problems (perhaps even bugs?), which is why they require explicit enabling in order to be used in code without getting warnings.

However, given that implicit conversions are in big part (if not most of the time) used for wrapping an object with an object of another type, and so are implicit classes—I'd appreciate you correcting me if I'm wrong—, why do the former require the import of scala.language.implicitConversions but the latter do not?

object Main extends App {
  implicit class StringFoo(x: String) {
    def fooWithImplicitClass(): Unit =
      println("foo with implicit class")
  }
  // => silence.

  "asd".fooWithImplicitClass()

  /************************/

  class Foo(x: String) {
    def fooWithImplicitDef(): Unit =
      println("foo with implicit def")
  }
  implicit def string2Foo(x: String) = new Foo(x)
  // => warning: implicit conversion method string2Foo should be enabled

  "asd".fooWithImplicitDef()
}

回答1:

Implicit classes effectively only add new methods (or traits), and they are only ever used when these added methods are called (or the implicit class is used explicitly, but this rarely happens in practice). Implicit conversions to existing types, on the other hand, can be invoked with less visibility to the programmer.



回答2:

IMO, there is no fundamental difference between an implicit class and an implicit conversion as regards the confusion they might potentially incur, thus both should have been warned.

But by defining a class as implicit, it's like explicitly suppressing the warning by telling the compiler that "I'm an adult, I know what I'm doing. THIS CLASS IS INTENDED TO BE USED THIS WAY (possibly as an extension wrapper)." Therefore no warnings will be given since you, as the creator of the class, have made it clear that using implicitly is how this class is supposed to work or how the class is allowed to be used, compiler should certainly trust you.

You can, on the other hand, convert an object to whichever class by using implicit conversion, no matter if the target class is intended to be used implicitly. This is the source of many troubles, and also what Scala is trying to prevent.