Перегрузка оператора косой черты для вызова методов пользовательского объекта - PullRequest
1 голос
/ 17 июня 2019

Я создал класс с именем Rational, который представляет собой простую абстракцию над рациональными числами.Его конструктор принимает два аргумента, которые он хранит как numer и denom.Моя цель - дать возможность пользователю библиотеки писать любое выражение формы x/y (например, (2/3, 3/1), а также выражения, использующие рациональные числа (2/3 * 15/16 - 10/31 и т. Д.), Как обычно,но вместо того выражения, которое отправляется в FPU для частного, я хочу, чтобы аргументы были переданы в свежий экземпляр Rational, который затем будет возвращен. Методы и поля Rational aren 'Это важно, за исключением тривиального toString:

override def toString : String = numer + "/" + denom 

Основываясь на обсуждении здесь , я создал простую черту Rationalizer:

trait Rationalizer {
  implicit class WrappedInt(val x: Int) {
    def / (y:Int): Rational = new Rational(x, y)
  }
}

и затем я сделал небольшой App, чтобы проверить, был ли вызван Rational::toString, когда я пытался напечатать 2/3:

object Runner extends App with Rationalizer{
  println(2/3)
}

К сожалению, кажется, что оператор придерживается интерпретации своих операндов какInt с и сообщает 0, усеченный результат 2/3.

Конечно, если я изменю имя оператора, переопределенного в Rationalizer, на что-то другое, например, foo:

trait Rationalizer {
  implicit class WrappedInt(val x: Int) {
    def foo (y:Int): Rational = new Rational(x, y)
  }
}

и внесите соответствующее изменение в мой Runner экземпляр:

object Runner extends App with Rationalizer {
  println(2 foo 3)
}

тогда Rational::toString называется просто отлично.Кроме того, в первой конфигурации (/ вместо foo) явно задается левый операнд экземпляра / WrappedInt и вызывается Runner следующим образом:

object Runner extends App with Rationalizer{
  println(new WrappedInt(2) / 3)
}

также дает желаемый результат.Однако моя цель состоит в том, чтобы один и тот же оператор '/' отвечал по-разному в зависимости от того, смешивается ли Runner с Rationalizer или нет (так, минимальное изменение исходного кода), чтобы я мог сравнить точностьвычисления против скорости вычислений и генерировать некоторые графики.

Есть идеи о перегрузке / и смешивании этой черты с моим Runner?

...