2012-03-13 5 views
4

У меня есть набор объектов модели и набор объектов-оберток, чтобы дать им дополнительную функциональность.Scala - использовать объект-компаньон как сокращенный аргумент для приема функции

Я хотел бы иметь возможность конвертировать коллекции типовых объектов обертки объектов сжато, используя то же сокращенное, что позволяет писать 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) 

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

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

+0

Я бы открыл билет об этом. Поведение выглядит подозрительно непоследовательным. –

+0

Я сделаю так ... – Russell

ответ

10

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

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) } 
+0

Забавные вещи в том, что, согласно спецификации scala, встроенный объект компаньона не реализует признак функции. Может быть, есть еще одно объяснение. – Nicolas

+1

Это работает так, что оно считается принятым, спасибо. Но мне было бы интересно узнать, что вызывает разницу. Догадайтесь, но мне интересно, делает ли встроенный объект-компаньон чем-то вроде предоставления неявного преобразования в 'Function'? – Russell

+0

Я нашел это поведение несколько дней назад, и это было странно для меня тоже. –

4

По какой-то причине, эти работы:

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

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

+0

Да, это суть проблемы, которую я испытываю. – Russell

Смежные вопросы