2010-11-10 38 views
4

以下example from 斯卡拉之旅显示了基于类型如何使用隐式提供适当的缺失成员(add和unit)。编译器将在范围内选择正确的隐式对象。该库也使用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) 

在哪里我主要使用隐式对自己保存一些打字在调用站点上传递参数时。

+1

虽然根据语言规则有效,但我个人不会在这些情况下使用暗示。我会用它们: 1)根据调用环境改变方法的行为。 2)对调用取决于周围类的类型参数或方法本身。 但是,这只是我个人的看法,何时以及如何使用它们。也许还有其他有效和有用的模式。 – axel22 2010-11-10 16:36:20

回答

3

这是一个很好的用例。实际上,当范围决定要使用的参数时,我推荐这样做。它提供了一种优雅的方式将某种上下文传递给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。

+0

是的,我可以看到这是如何有用。引发这个问题的用例是沿着这些线的,但我没有想到“上下文”这个词...... – huynhjl 2010-11-11 00:43:45

2

它看起来并不像一个惯用的implicits,它倾向于适用于类型类和依赖注入。绝对没有点在经过大约不带任何成员的一类...

这也是比较常见的进行调用,以(new B).foo

之前定义I类型的隐式VAL或对象说了这么多,您所提供这显然是一个非常抽象的例子。因此,想象一个合理的使用情况下的相似模式的含义是不难的。