2015-05-15 2 views
0

Возможно ли переопределить тип 'val' в конструкторе Scala?Как переопределить параметр в конструкторе класса Scala

Учитывая такой класс, как это:

class GPPerson (id: Option[GPID], created: Option[DateTime], active: Boolean, primaryEmail: String) 

Я хотел бы создать конструктор, который по сути может сделать это:

if (created == None) created = new DateTime 

Другими словами, если значение None является поставки, замените его экземпляром DateTime. Уловка заключается в том, что я пытаюсь избежать использования сопутствующего объекта, а «созданный» объект должен быть «val» (не может сделать его «var»).

+0

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

+1

Сопутствующий объект будет усложнять ситуацию. Это не невозможно, но, как я сказал, «пытаюсь избежать». Это классы TableQuery в Slick, а введение сопутствующего объекта приводит к разрыву неявного разговора ... (например, метод tupled() «потерян» из-за методов apply()). Это может быть исправлено путем реализации явного tupled() BUT ... это в основном шаблон для всех наших моделей, поэтому я стараюсь держать его как можно проще. – Zac

ответ

2

параметры конструктора могут иметь значение по умолчанию:

class GPPerson (id: Option[GPID], created: Option[DateTime] = Some(new DateTime), active: Boolean, primaryEmail: String) 
// to instantiate it: 
new GPPerson(id = Some(id), active = false, primaryEmail = myEmail) 

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

class GPPerson (id: Option[GPID], active: Boolean, primaryEmail: String, created: Option[DateTime] = Some(new DateTime)) 
// to instantiate it: 
new GPPerson(Some(id), false, myEmail) 
+0

Спасибо Jhonny, отличные предложения (я стараюсь избегать изменения порядка, так как наш «стандарт» для наших объектов модели должен иметь идентификатор и создать дату первых двух параметров последовательно - да, это еще больше усложняет ситуацию). – Zac

1

One подход

class GPPerson (id: Option[GPID], _created: Option[DateTime], active: Boolean, primaryEmail: String) { 
    val created = _created.getOrElse(new DateTime) 
} 

Другой:

class GPPerson (id: Option[GPID], created: DateTime, active: Boolean, primaryEmail: String) { 
    def this(id: Option[GPID], _created: Option[DateTime], active: Boolean, primaryEmail: String) = this(id, _created.getOrElse(new DateTime), active, primaryEmail) 
} 

хотя для этого конкретного случая я бы пошел с решением @ JhonnyEverson.

+0

Хорошие предложения - спасибо за размышление вне коробки немного! К сожалению, это не сработает, так как это модельный объект, а затем попытается сохранить _created ... (пытаясь получить ** точно **, что мы хотим, невозможно из-за того, как работает Slick, кажется, компромисс между «элегантный» API по сравнению с «простым» шаблоном проектирования). – Zac

+0

Во втором варианте '_created' не является полем, и он должен работать. С другой стороны, повторение таких вторичных конструкторов для всех объектов модели было бы действительно yucky. Можно было бы избежать с помощью макрокоманды, я думаю, но это слишком тяжелое решение, когда параметр по умолчанию будет работать также :) –

+0

Я согласен ... хотя заманчиво. И вы можете пометить основной аргумент конструктора как закрытый, чтобы скрыть необязательную версию («class GPPerson private (id: ...», но ... как вы говорите, вроде yucky. Тем не менее, он достигает цели ... – Zac

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