Scala - использовать сопутствующий объект в качестве сокращенного аргумента для блока, принимающего функцию - PullRequest
4 голосов
/ 13 марта 2012

У меня есть набор объектов модели и набор объектов-оболочек для придания им дополнительной функциональности.

Я бы хотел иметь возможность кратко преобразовывать коллекции объектов-моделей в объекты-обертки, используя те же сокращения.это позволяет вам написать List("x", "y", "z").foreach(println), например:

class Model
class ModelWrapper(val m: Model)
object ModelWrapper { def apply(model: Model) = new ModelWrapper(model) }

val m1 = new Model; val m2 = new Model; val m3 = new Model

List(m1, m2, m3).map(ModelWrapper)

, чтобы ModelWrapper, переданный в качестве аргумента, был преобразован в ModelWrapper(_), вызов объекта-компаньона.

Однако, когда я пытаюсь это сделать, я получаю ошибку несоответствия типов, подобную этой:

<console>:14: error: type mismatch;
 found   : ModelWrapper.type (with underlying type object ModelWrapper)
 required: Model => ?
                  List(m1, m2, m3).map(ModelWrapper)

Однако , если я сделаю ModelWrapper a case class и удалю собеседникаобъект, это работает.Я не хочу превращать его в класс case, поскольку добавляемое им поведение не вписывается в общий подход к классам case.Например, два класса-обертки с одним и тем же классом модели в качестве параметра не обязательно равны.

Что я хотел бы знать, в чем заключается разница между классом случая и объектом-компаньоном в этом случае?Могу ли я получить то, что я хочу, без использования класса case?

Ответы [ 3 ]

10 голосов
/ 13 марта 2012

Ваш объект-компаньон должен быть функцией:

object ModelWrapper extends Function1[Model, ModelWrapper] { def apply(model: Model) = new ModelWrapper(model) }

Или, возможно, вы предпочтете эту аббревиатуру:

object ModelWrapper extends (Model => ModelWrapper) { def apply(model: Model) = new ModelWrapper(model) }
4 голосов
/ 13 марта 2012

Почему-то эти работы:

  List(m1, m2, m3).map(ModelWrapper(_))
  List(m1, m2, m3).map(ModelWrapper.apply)

Кажется, для case классов, поскольку объект-компаньон создается компилятором, а не вами, он знает, что вы ссылаетесь на ModelWrapper.apply. Когда есть компаньон, он думает, что вы имеете в виду компаньона.

1 голос
/ 29 марта 2012

Мартин Одерский отвечает на вопрос по истории на этот повторяющийся вопрос:

Почему сопутствующие объекты класса case расширяют FunctionN?

Этот вопрос также предоставляет немного больше контекста.

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