为什么隐式defs需要implicitConversions而不是类?

时间:2013-09-20 10:59:36

标签: scala type-conversion implicit-conversion

据我所知,隐式转换可能导致可能难以理解的代码,或代码遭遇其他问题(甚至可能是错误?),这就是为什么它们需要显式启用才能在代码中使用而不会收到警告

然而,鉴于隐式转换在很大程度上(如果不是大部分时间)用于包装具有另一种类型的对象的对象,那么隐式类也是如此 - 如果我是的话,我会感谢你纠正我错误 - 为什么前者需要导入scala.language.implicitConversions但后者不需要?

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()
}

2 个答案:

答案 0 :(得分:21)

隐式类有效地仅添加新方法(或特征),并且仅在调用这些添加的方法时使用它们(或者显式使用隐式类,但这在实践中很少发生)。另一方面,对程序员的可见性较低,可以调用对现有类型的隐式转换。

答案 1 :(得分:0)

IMO,隐式类和隐式转换之间没有根本区别,因为它们可能会产生混淆,因此两者都应该被警告。

但是通过将一个类定义为隐式,它就像通过告诉编译器“我是一个成年人,我知道我在做什么来明确地抑制警告。这个类本打算以这种方式使用(可能作为一个扩展包装器。)“因此,由于您作为类的创建者已明确表示隐式使用此类应该如何工作或如何允许使用该类,因此编译器应该信任您,因此不会发出警告。

另一方面,无论是否打算隐式使用目标类,您都可以使用隐式转换将对象转换为任何类。这是许多问题的根源,也是Scala试图阻止的问题。