2011-07-29 9 views
10

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

Что у меня есть:

class Foo { 
     //some init code 

     //... 
    } 

То, что я хотел бы (но не работаю, как он хочет, чтобы я вызвать другой конструктор первый):

class Foo { 
     // The only constructor 
     def this() = { 
      //some init code 
     } 

     //... 
    } 

ответ

16

Всех классов в Scala есть первичный конструктор и, возможно, некоторые вспомогательные конструкторы (которые должны отнестись к основному конструктору или другому вспомогательному конструктору).

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

// Primary constructor takes a String 
class Foo(s: String) { 
    // Auxiliary constructor also takes a String?? (compile error) 
    def this(a: String) { 
     this(a) 
    } 
} 

Это не что-то делать с тем фактом, что конструктор не является не-арг; следующие компилирует, например:

class Foo(s: String) { 
    // alternative no-arg constructor (with different signature from primary) 
    def this() { 
     this("Default value from auxiliary constructor") 
    } 
} 

В частности, в вашем втором примере, ваш комментарий «единственный конструктор» является неправильно. Вспомогательные конструкторы всегда вторичны для основного конструктора и никогда не могут быть единственным конструктором.

FWIW, первый пример - единственный вариант, открытый для вас, но он выглядит хорошо для меня. Если вы только начали использовать Scala, я уверен, что он начнет чувствовать себя достаточно скоро - и очень важно избегать способов Java-esque делать вещи, когда есть больше идиоматических альтернатив.

+2

Вспомогательные конструкторы могут также отнестись к другим вспомогательным конструкторам, определенным ранее. –

+0

@ jean-phillipe: Спасибо, ты прав. Я просто понял, что сам не точный в более широком плане; пост исправлен. –

+0

Спасибо, что-то беспокоило меня о конструкторах Scala с самого начала, но это никогда не было на моем пути слишком много ... теперь все ясно. – HairyFotr

4

Ну, ставя код инициализации в тело класса, это единственный способ иметь конструктор без параметров. Я полагаю, что если вы хотите, вы могли бы сделать что-то вроде:

class Foo { 

    private def init { 
    //init code here 
    } 

    init() 
} 

Это как можно ближе.

10

Для чего вы можете добавить дополнительную область для «отметки» кода инициализации.

class Foo { 
    { 
     // init code here 
    } 
} 
+0

Мне это очень нравится. Исходя из Java, наличие кода конструктора по умолчанию в корпусе класса просто слишком беспорядочно! –

+0

Thx для приятных слов, но если бы я был вами, я бы не привык к этому.Я был в ландшафте Скала в течение последних 7 лет и не видел, чтобы этот образец использовался где-то даже один раз. ;) – agilesteel

4

Код инициализации является тело метода. Но вы можете это сделать, если это вас очень беспокоит:

class Foo { 
     locally { 
      //some init code 
     } 
} 
+0

Что такое «локально» в этом контексте? Это зарезервированное слово? Можно ли ссылаться где угодно? –

+0

@user Это встроенный метод, определенный в 'Predef', который возвращает значение блока. На него можно ссылаться где угодно. –

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