Понимание того, почему «pimp my library» было определено таким образом в Scala - PullRequest
18 голосов
/ 16 декабря 2009

Если я хочу добавить метод в класс в Scala, мне нужно сделать что-то вроде:

class RichFoo(f: Foo) {
  def newMethod = f.bar()
}
object RichFoo {
  implicit def foo2Rich(f: Foo) = new RichFoo(f)
}

Тогда f.newMethod приведет к созданию экземпляра RichFoo и вызову его метод.

Я пытаюсь понять, почему он не был определен так же, как Ruby:

override class Foo {
  def newMethod = bar
}

Компилятор может просмотреть это определение и создать класс FooOverride со статическим методом newMethod, который получает параметр типа Foo и вызывает его метод bar. Вот как Scala реализует черты. Мне все еще нужно импортировать пакет, содержащий переопределение Foo, чтобы использовать его.

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

Я уверен, что что-то пропустил и хотел бы понять, что.

Ответы [ 2 ]

13 голосов
/ 16 декабря 2009

Существуют и другие применения неявных преобразований, кроме идиомы «pimp my library», так что на самом деле дело не в том, «почему они не сделали этого вместо этого?», А «почему они не сделали это как Что ж?". Конечно, я не вижу причин, по которым синтаксис методов расширения не может быть добавлен, как вы предлагаете, и он, вероятно, будет несколько чище, но в этом нет особой необходимости, учитывая, что язык уже поддерживает способ достижения того же эффекта. .

Обновление за октябрь 2011 года:

Существует новое предложение добавить синтаксический сахар для этого варианта использования: http://scala.github.com/sips/pending/implicit-classes.html

8 голосов
/ 16 декабря 2009

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

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

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

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

implicit def fooBar(f: Foo) = new { def newMethod = bar }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...