【问题标题】:Scala implicit object vs implicit valScala 隐式对象与隐式 val
【发布时间】:2016-01-23 21:54:35
【问题描述】:

我见过两种在 Scala 中为 typeclass 模式 声明 implicit 的方法(一种比另一种少)。

implicit val instance1 = new Typeclass { def do = ??? }
implicit object instance2 extends Typeclass { def do = ??? }

它们有何不同?一个人是否应该在某些时候更喜欢另一个?我发现implicit valimplicit object 更常用,我还没有找到很多关于implicit object 的资源。

【问题讨论】:

    标签: scala implicit


    【解决方案1】:

    一个区别是object 版本将被延迟初始化,即它的构造函数在第一次使用之前不会被调用。例如:

    trait Incrementer[T] {
      def inc(x: T)
    }
    
    def increment[T](x: T)(implicit ev: Incrementer[T]) = ev.inc(x)
    
    implicit object IntIncrementer extends Incrementer[Int] {
      println("IntIncrementer is being constructed...")
    
      def inc(x: Int) = x + 1
    }
    
    implicit val DoubleIncrementer extends Incrementer[Double] {
      println("DoubleIncrementer is being constructed...")
    
      def inc(x: Double) = x + 1D
    }
    

    请注意,在使用之前,您不会看到来自IntIncrementer 的消息,例如

    increment(1)  //this prints "IntIncrementer is being constructed..."
    

    但是,来自DoubleIncrementer 的消息将在定义后显示。所以implicit object的初始化是惰性的,而implicit val的初始化是严格的。

    【讨论】:

    • 那么,使用 implicit object 还是 val 的决定取决于是更喜欢惰性初始化还是严格初始化?
    • 这可能是一个考虑因素(尽管您总是可以使用lazy val 来获得val 的懒惰),但不是唯一的考虑因素。例如,val 成员可以在子类中被覆盖,而 object 成员不能。我敢肯定还有很多其他差​​异。
    猜你喜欢
    • 1970-01-01
    • 2021-03-23
    • 2013-03-08
    • 1970-01-01
    • 2020-12-08
    • 2018-02-01
    • 1970-01-01
    • 2012-04-27
    • 2013-05-31
    相关资源
    最近更新 更多