是否可以使用不同的实现编写类型类?

时间:2015-04-01 12:20:34

标签: scala typeclass implicit

这是我之前question

的后续内容

假设我有一个特征ConverterTo两个实现:

trait ConverterTo[T] {
  def convert(s: String): Option[T]
}

object Converters1 {
  implicit val toInt: ConverterTo[Int] = ???
}

object Converters2 {
  implicit val toInt: ConverterTo[Int] = ???
}

我还有两个课程A1A2

class A1 {
  def foo[T](s: String)(implicit ct: ConverterTo[T]) = ct.convert(s) 
}

class A2 {
  def bar[T](s: String)(implicit ct: ConverterTo[T]) = ct.convert(s)
}

现在,我希望任何foo[T]来电使用Converters1和任何bar[T]来电使用Converters2 ,无需导入Converters1和客户端代码中的Converters2

val a1 = new A1()
val a2 = new A2()
...
val i = a1.foo[Int]("0") // use Converters1 without importing it
...
val j = a2.bar[Int]("0") // use Converters2 without importing it

可以在Scala中完成吗?

2 个答案:

答案 0 :(得分:1)

在班级中导入Converters

class A1 {
 import Converters1._
 private def fooPrivate[T](s: String)(implicit ct: ConverterTo[T]) = ct.convert(s) 
 def fooShownToClient[T](s: String) = fooPrivate(s)
}

然后使用显示给客户端的方法

val a1 = new A1()
a1.fooShownToClient[Int]("0")

现在客户端并不知道转换器。

答案 1 :(得分:1)

如果您有需要更多本地控制的情况;您可以选择明确地传递implicit参数

val i = a1.foo("0")(Converters1.toInt)
val j = a2.foo("0")(Converters2.toInt)

这实际上取决于你想要什么。如果要在不污染本地范围的情况下选择特定实现,请执行此操作(或引入新范围)。如果类需要特定实现,mohit的解决方案很有效(尽管在这种情况下,将此依赖关系声明为implicit并不存在真正的意义)。