Подтвердить что ты не робот

Понимание того, почему "сутенер моей библиотеки" был определен таким образом в Scala

Если я хочу добавить метод в класс в 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, чтобы использовать его.

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

В качестве последней заметки, если вы хотите коротко, вы можете сделать:

implicit def fooBar(f: Foo) = new { def newMethod = bar }