Как работает «1 * BigInt (1)» и как я могу сделать то же самое? - PullRequest
3 голосов
/ 04 октября 2011

Я пытаюсь реализовать какой-то тип номера и сталкиваюсь с проблемой,

mynum * 1

работает, но не

1 * mynum

Я пытался определить неявное преобразование, как это

case class Num(v: Int) {
  def * (o: Int) = new Num(v*o)
}

implicit def int2Num(v: Int) = Num(v)

но это не похоже на работу, потому что я всегда получаю следующую ошибку:

scala> 1 * new Num(2)
<console>:14: error: overloaded method value * with alternatives:
  (x: Double)Double <and>
  (x: Float)Float <and>
  (x: Long)Long <and>
  (x: Int)Int <and>
  (x: Char)Int <and>
  (x: Short)Int <and>
  (x: Byte)Int
 cannot be applied to (Num)
              1 * new Num(2)
                ^

С другой стороны

1 * BigInt(1)

работает, поэтому должен быть способ, хотя я не мог определить решение, глядя на код.

Какой механизм заставить его работать?

РЕДАКТИРОВАТЬ: Я создал новый вопрос с фактической проблемой, с которой я столкнулся, Почему неявное преобразование не рассматривается в этом случае с общими параметрами? .

Ответы [ 2 ]

9 голосов
/ 04 октября 2011

При сбое приложения a.meth(args) компилятор ищет неявное представление из a во что-то, имеющее метод meth. Подойдет любое неявное значение или метод, соответствующий A => { def meth(...) }. Если он найден, код переписывается как view(a).meth(args).

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

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

Если это не удается, он выглядит в неявной области видимости. Он состоит из сопутствующих объектов «частей» того типа, который мы ищем. В данном случае мы следуем за A => { def meth(...) }, поэтому мы просто смотрим на объект-компаньон A (и его супертипы).

В транке Scala неявная область действия расширена до крошечного бита , чтобы включить сопутствующие объекты типов аргументов . Не уверен, что это было уже в 2.9.1, возможно, дружелюбный читатель выяснит это и обновит этот ответ.

Так 1 + BigInt(2) расширен до BigInt.int2bigInt(1) + BigInt(2)

7 голосов
/ 04 октября 2011

Я думаю, что в вашем классе Num отсутствует метод *, который принимает Num в качестве аргумента.

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