带有私有构造函数和隐式参数的Scala类

时间:2016-10-19 14:41:32

标签: scala constructor implicits

我想使用私有构造函数向类中添加隐式参数。这是一个简化的例子:

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

如果我想将 Pimp my library 模式应用于带有Ordered [T]的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)

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

编辑:经过一些实验后,似乎用隐式参数重新定义构造函数是个问题。不是构造函数是私有的。

2 个答案:

答案 0 :(得分:3)

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

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

我为发送垃圾邮件而道歉,无论如何我会接受任何提供更深入解释的答案。

答案 1 :(得分:3)

Scala提供2种口味的排序,一种是通过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)
  }
}

如果使用&#34; explicit&#34;来定义它。语法:

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