简体   繁体   English

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

[英]Scala class with a private constructor and implicit parameter

I would like to add an implicit parameter to a class with a private constructor. 我想向带有私有构造函数的类添加隐式参数。 Here as a simplified example: 作为简化示例:

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

If I would like to apply Pimp my library pattern to T with Ordered[T], I would need to use (the deprecated) view bound like so: 如果我想使用Ordered [T]将Pimp我的库模式应用于T,则需要使用(已弃用的)视图绑定,如下所示:

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

And this works. 这可行。 However, to avoid the deprecated syntactic sugar I would like to pass the implicit parameter to the class. 但是,为了避免使用过时的语法糖,我想将隐式参数传递给该类。 Unfortunately, this is where I'm probably doing something wrong: 不幸的是,这可能是我做错事的地方:

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

For the above code, the compiler generates the following error: 对于以上代码,编译器将生成以下错误:

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

While if I try to pass the implicit parameter directly like so: 而如果我尝试像这样直接传递隐式参数:

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

I get this: 我得到这个:

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

How does one pass an implicit parameter in this case? 在这种情况下,如何传递隐式参数?

EDIT: After some more experimentation it seems that redefining the constructor with implicit parameter is the problem. 编辑:经过更多的实验后,似乎用隐式参数重新定义构造函数是问题。 Not the fact that the constructor is private. 并非构造函数是私有的。

I found an answer, it seems that I need to explicitly define the implicit parameter for the parameterless constructor, eg: 我找到了答案,看来我需要为无参数构造函数显式定义隐式参数,例如:

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

I apologize for spamming SO, in any case I will accept any answer that provides a more in depth explanation. 对于垃圾邮件,我深表歉意,无论如何,我将接受任何提供更深入说明的答案。

Scala provides ordering in 2 flavours, one via inheritance with Ordered and the other one which is actually a lot more appropriate in here is via context bounds using the Ordering typeclass. Scala提供两种排序方式,一种是通过继承Ordered ,而另一种实际上更合适,这是通过使用Ordering类型类的上下文边界。

Your approach is not actually idiomatic, and if you had something that actually used the implicit you provided, you would get an ambiguous implicit exception at compile time, because both the constructor and the method define the same implicit. 您的方法实际上并不是惯用的,如果您有一些东西实际使用了您提供的隐式,则在编译时会得到一个模棱两可的隐式异常,因为构造函数和方法都定义了相同的隐式。

What I would do is: 我要做的是:

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

This is actually shorthand syntax for: 这实际上是以下内容的简写语法:

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

You can then use this argument either explicitly or implicitly . 然后,您可以显式或implicitly使用此参数。 If you define it with the shorthand T : Ordering syntax. 如果使用速记T : Ordering定义它T : Ordering语法。

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

If you define it with the "explicit" syntax: 如果使用“显式”语法定义它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM