这是我之前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] = ???
}
我还有两个课程A1
和A2
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中完成吗?
答案 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
并不存在真正的意义)。