【问题标题】:Scala class with a private constructor and implicit parameter具有私有构造函数和隐式参数的 Scala 类
【发布时间】:2016-10-20 05:14:18
【问题描述】:

我想为具有私有构造函数的类添加一个隐式参数。这里作为一个简化的例子:

class A[T] private(a:Int){ 
  def this()=this(0)
}

如果我想使用 Ordered[T] 将 Pimp my library 模式应用到 T,我需要使用(已弃用的)视图绑定,如下所示:

class A[T <% Ordered[T]] private(a:Int){ 
  def this()=this(0)
}

这很有效。但是,为了避免不推荐使用的语法糖,我想将隐式参数传递给类。不幸的是,这可能是我做错了什么:

class A[T] private(a:Int)(implicit conv:T=>Ordered[T]){ 
  def this()=this(0)
}

对于上述代码,编译器会产生如下错误:

error: No implicit view available from T => Ordered[T].
       def this()=this(0)

如果我尝试像这样直接传递隐式参数:

class A[T] private(a:Int)(implicit conv:T=>Ordered[T]){ 
  def this()=this(0)(conv)
}

我明白了:

error: not found: value conv
       def this()=this(0)(conv)

在这种情况下如何传递隐式参数?

编辑:经过更多实验后,似乎用隐式参数重新定义构造函数是问题所在。不是构造函数是私有的事实。

【问题讨论】:

    标签: scala constructor implicits


    【解决方案1】:

    我找到了答案,看来我需要为无参构造函数显式定义隐式参数,例如:

    class A[T] private(a:Int)(implicit conv:T=>Ordered[T]){ 
      def this()(implicit conv:T=>Ordered[T])=this(0)
    }
    

    对于发送垃圾邮件,我深表歉意,无论如何我都会接受任何提供更深入解释的答案。

    【讨论】:

    • 你不需要道歉,回答你自己的问题是完全可以接受的。
    • @Krle 这在我的书中有相当大的代码味道。为一个人正确缩进代码将是一个不错的起点,但我不会那样做。相反,我会将这个重载的构造函数移动到具有相同隐式的伴随应用方法,看起来稍微干净一些。
    • @flavian 谢谢,我会这样做的。不过,您能详细说明原因吗?对于缩进和伴随对象...
    【解决方案2】:

    Scala 提供了两种排序方式,一种是通过Ordered 的继承,另一种实际上在这里更合适的是通过使用Ordering 类型类的上下文边界。

    您的方法实际上并不是惯用的,如果您有一些实际使用了您提供的隐式的东西,您会在编译时得到一个模棱两可的隐式异常,因为构造函数和方法都定义了相同的隐式。

    我会做的是:

    class A[T : Ordering] private(a: Int)
    

    这实际上是以下的简写语法:

    class A[T] private(a: Int)(implicit ev: Ordering[T])
    

    然后您可以显式或implicitly 使用此参数。 如果您使用简写 T : Ordering 语法定义它。

    class A[T : Ordering] private(a: Int) {
      def revSorter(list: List[T]): List[T] = {
        list.sorted(implicitly[Ordering[T]].reverse)
      }
    }
    

    如果你用“显式”语法定义它:

    class A[T] private(a: Int)(implicit ev: Ordering[T]) {
          def revSorter(list: List[T]): List[T] = {
            list.sorted(ev.reverse)
          }
        }
    

    【讨论】:

    • 是的,我同意上下文边界,但我想重点是关于如何使用隐式参数重新定义构造函数。我应该在示例中使用通用类 B,而不是 Ordered[T]。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多