Переопределение арифметических операторов в Int с помощью неявных преобразований - PullRequest
4 голосов
/ 14 декабря 2010

Скажите, что по эстетическим соображениям я хочу иметь возможность написать:

3 / 4

и иметь / быть методом класса, в который существует неявное преобразование из Int в, например:

class Foo(val i: Int) {
  def /(that: Int) = // something
}

implicit def intToFoo(i: Int) = new Foo(i)

Возможно ли это вообще, т. Е. Возможно ли "отключить" метод / в Int?

Ответы [ 3 ]

7 голосов
/ 14 декабря 2010

Короче говоря: нет, вы не можете.

Неявное разрешение будет иметь место, только если вы попытаетесь вызвать метод, который еще не существует.

Более «идиоматическим» решением было бы создание собственного типа псевдо-числа, например:

case class Rational(a: Int, b: Int) {
  // other methods
}

val foo = Rational(3, 4)

или

case class Path(value: String) {
  def /(other: String): Path = ...
}

val p = Path("3") / "4"
2 голосов
/ 15 декабря 2010

Есть ли причина, по которой что-то типа

trait PathElement[T] { val value: T }
case class IntElement(value: Int) extends PathElement[Int]
case class StringElement(value: String) extends PathElement[String]

case class Path(parts: Seq[PathElement[_]]) {
   def /(other: Path): Path = copy(parts = parts ++ other.parts)
}
object Path {
   def apply(part: PathElement[_]): Path = Path(List(part))
   implicit def int2path(i: Int): Path = Path(IntElement(i))
   implicit def str2path(s: String): Path = Path(StringElement(s))
}

не будет работать для вас? Это позволит вам написать, например,

import Path._
"foo" / 3 / 4 / "bar"

Это работает, потому что String не имеет своего собственного / метода, поэтому первый "foo" неявно преобразуется в Path. Если бы вы начинали Path с Int, вам пришлось бы преобразовать его явно, но вы получите другие Int бесплатно.

1 голос
/ 15 декабря 2010

Конечно, я могу только догадываться, чего вы действительно хотите достичь, но я предполагаю, что вы не просто хотите сопоставлять конкретные URL-адреса, но также извлекаете информацию из заданных строк.Например, когда задано "/foo/21", вы не просто хотите знать, что это соответствует некоторому "foo" / 21, но вы хотите сделать что-то со значением 21.

Я нашел процесс сопоставления URI в Lift toбыть весьма полезным, так что, возможно, это подходит для вашего случая использования.(Я использую очень упрощенную версию, конечно.) Это сделано со списками, которые немного упрощают сопоставление, но это также означает, что вам придется использовать :: вместо /.

Но не в этом суть: то, что я хочу показать, - это преимущество , а не , использующее неявные преобразования и мощь экстракторов.неявное преобразование Int в String вы можете получить целочисленное значение из строки тогда и только тогда, когда оно конвертируемо, и, конечно, использовать его немедленно.Очевидно, что если вам не нравится наименование, вы можете изменить его на более ненавязчивое, но если вы действительно хотите выполнить сопоставление URL, вам, возможно, не следует конвертировать все неявно.

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