隐式参数的有效用法

时间:2010-11-10 14:14:09

标签: scala implicit

来自 Scala之旅的以下example显示了隐式如何用于根据类型提供适当的缺失成员(添加和单位)。编译器将在范围内选择正确的隐式对象。例如,该库也使用List.sortByOrderingList.sumNumeric

但是,在B类中,以下用法是隐式参数的有效/推荐用法(而不是在A类中不使用隐式):

class I

class A {
  def foo(i:I) { bar(i) }
  def bar(i:I) { baz(i) }
  def baz(i:I) { println("A baz " + i) }
}
(new A).foo(new I)

class B {
  def foo(implicit i:I) { bar }
  def bar(implicit i:I) { baz }
  def baz(implicit i:I) { println("B baz " + i) }
}
(new B).foo(new I)

当我在堆栈中传递参数时,我主要使用隐式来保存自己在调用站点的一些键入。

2 个答案:

答案 0 :(得分:3)

它看起来并不像implicits的习惯用法,它往往适用于类型类和依赖注入。关于没有成员的课程,绝对没有意义......

在调用I之前定义(new B).foo类型的隐式val或对象也更常见

说了这么多,你提供了一个非常抽象的例子。因此,想象一个合理的用例来表示类似模式的implicits并不是很难。

答案 1 :(得分:3)

这是一个很好的用例。当scope确定要使用的参数时,我实际上建议这样做。它提供了一种将某种上下文传递给Plugin类的优雅方法,以便实用程序函数将使用上下文。例如:

trait Context

object UtilityLib {
  def performHandyFunction(implicit x : Context) : SomeResult = ...
}

trait Plugin {
   def doYourThing(implicit ctx : Context) : Unit
}

class MyPlugin extends Plugin {
  def doYourThing(implicit ctx : Context) : Unit = {
    UtilityLib.performHandyFunction
  }
}

SomePluginAPI.register(new MyPlugin)

您可以在database migration system I was toying中看到一个示例。查看Migration类及其MigrationContext。