Scala: два неявных аргумента с одинаковым объявлением - PullRequest
7 голосов
/ 31 октября 2011

У меня есть следующий класс:

class Example(implicit doSomething1: (Double, Double) => Double, implicit doSomething2: (Double, Double) => Double)
{
  //..
}

Как видите, конструктор имеет два неявных аргумента (функции) с одинаковым объявлением. Но я хочу «ввести» два разных определения. Возможно ли это неявным образом? Или это возможно только известным явным образом?

Спасибо

Ответы [ 2 ]

10 голосов
/ 31 октября 2011

Если компилятор ищет implicit (Double, Double) => Double в неявной области видимости, либо он точно имеет более высокий приоритет, и он выберет его один раз, либо его нет (либо в неявной области его вообще нет, либо больше чем один с наивысшим приоритетом), и будет ошибка из-за отсутствия неявного значения.

Если вы хотите различать, у вас может быть два разных типа, оба расширяющие Function2 [Double, Double, Double]. Например

trait Addition extends Function[Double, Double, Double]
trait Multiplication extends Function[Double, Double, Double]
class Example(implicit addition: Addition, implicit multiplication: Multiplication) 

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

trait Ring {
  def add(x: Double, y: Double): Double
  def mult(x: Double, y: Double): Double
}
// or `case class Ring(
//       addition: (Double, Double) => Double, 
//       multiplication: (Double, Double) => Double)
class Example(implicit ring: Ring)

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

implicit val addition = ...
implicit val multiplication = 
new Example

Вы могли бы также быть явным.

Кроме того, если ожидается, что большинство вызовов будут работать с одним и тем же значением, и вы просто хотите изменить несколько из них, вы можете использовать аргументы со значениями по умолчанию

class Example(doSomething1 : (Double, Double) => Double = <default value>, doSomething2  ...)

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

0 голосов
/ 31 октября 2011

Запись

class Example(implicit doSomething1: (Double, Double) => Double, doSomething2: (Double, Double) => Double)
{
  //..
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...