Вспомогательные конструкторы могут содержать более одного вызова другого конструктора, но их первым утверждением должно быть указано обращение.
Как объяснено в Программирование в Scala , гл. 6.7:
В Scala каждый вспомогательный конструктор должен вызывать другой конструктор того же класса, что и его первое действие. Другими словами, первый оператор в каждом вспомогательном конструкторе в каждом классе Scala будет иметь вид
this(. . . )
. Вызываемый конструктор является либо основным конструктором (как в примереRational
), либо другим вспомогательным конструктором, который идет текстовым образом перед вызывающим конструктором. Чистый эффект этого правила заключается в том, что каждый вызов конструктора в Scala в конечном итоге вызовет первичный конструктор класса. Таким образом, основной конструктор является единственной точкой входа в класс.Если вы знакомы с Java, вы можете задаться вопросом, почему правила Scala для конструкторов немного более ограничительны, чем Java. В Java конструктор должен либо вызывать другой конструктор того же класса, либо непосредственно вызывать конструктор суперкласса в качестве своего первого действия. В классе Scala только основной конструктор может вызывать конструктор суперкласса. Увеличенное ограничение в Scala - это действительно компромисс с дизайном, который нужно было заплатить в обмен на большую лаконичность и простоту конструкторов Scala по сравнению с Java.
blockquote>Как и в Java, можно обойти это ограничение, извлекая код, который должен быть выполнен до вызова основного конструктора, в отдельный метод. В Scala это немного сложнее, чем на Java, поскольку, по-видимому, вам нужно переместить этот вспомогательный метод в объект-компаньон, чтобы разрешить его вызывать из конструктора.
Кроме того, ваш конкретный случай неудобно, поскольку у вас есть два параметра конструктора и - хотя можно возвращать кортежи из функции - этот возвращенный кортеж затем не принимается в качестве списка аргументов в основной конструктор. Для обычных функций вы можете использовать
tupled
, но, увы, это не работает для конструкторов. Обходным путем было бы добавить еще один вспомогательный конструктор:object Wibble { private def init(baz: List[Any]): (Int, String) = { val bazLength = baz.length val someText = "baz length is " ++ bazLength.toString println("init") (bazLength, someText) } } class Wibble(foo: Int, bar: String) { println("Wibble wobble") def this(t: (Int, String)) = { this(t._1, t._2) println("You can execute more code here") } def this(baz: List[Any]) = { this(Wibble.init(baz)) println("You can also execute some code here") } }
Это, по крайней мере, работает, даже если это немного сложно.
scala> val w = new Wibble(List(1, 2, 3)) init Wibble wobble You can execute more code here You can also execute some code here w: Wibble = Wibble@b6e385
Обновить
Как отметил @ sschaef в своем комментарии, это можно упростить, используя фабричный метод в сопутствующем объекте:
object Wobble { def apply(baz: List[Any]): Wobble = { val bazLength = baz.length val someText = "baz length is " ++ bazLength.toString println("init") new Wobble(bazLength, someText) } } class Wobble(foo: Int, bar: String) { println("Wobble wibble") }
Таким образом, нам больше не нужно
new
, чтобы создать объект:scala> val w = Wobble(List(1, 2, 3)) init Wobble wibble w: Wobble = Wobble@47c130
Это известная проблема VS 2010. Согласно Microsoft, она будет исправлена для пакета обновления и следующего выпуска.
Обновление
Последний выпуск SP1 решает эту проблему. Обходные пути для удаления нежелательного перевода строки больше не нужны.
Форматирование Xml освобождает место. поскольку содержимое тегов XML не заботится о переносах строк и пробелах. если вы хотите иметь строковые значения, я настоятельно рекомендую поместить его в атрибуты вместо InnerValue
<setting name="TempPath" value="C:\TEMP">
</setting>