Допустимые использования неявных параметров - PullRequest
4 голосов
/ 10 ноября 2010

Следующий пример из Тур по Scala показывает, как неявные данные можно использовать для предоставления соответствующих пропущенных элементов (сложения и единицы) в зависимости от типа.Компилятор выберет правильный неявный объект в области видимости.Библиотека также использует это с List.sortBy и Ordering или List.sum и Numeric, например.

Однако следующее использование в классе 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 ]

3 голосов
/ 10 ноября 2010

Это очень хороший вариант использования.Я действительно рекомендую это, когда область действия определяет параметр для использования.Он предоставляет элегантный способ передать некоторый вид контекста в класс 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)

Вы можете увидеть пример в системе миграции базы данных , в которой я играл .Проверьте класс Migration и его MigrationContext.

3 голосов
/ 10 ноября 2010

Это не похоже на идиоматическое использование имплицитов, которые, как правило, подходят для классов типов и внедрения зависимостей.Нет абсолютно никакого смысла проходить мимо класса без членов ...

Также более распространено определение неявного val или объекта типа I перед вызовом (new B).foo

* 1006Сказав все это, вы привели явно очень абстрактный пример.Так что не сложно представить разумный вариант использования для последствий, которые следуют аналогичной схеме.
...