9

Я использую параметры по умолчанию Scala 2.8 для конструктора, а для соображений совместимости Java мне нужен конструктор no-arg, который использует параметры по умолчанию.Scala extra no-arg constructor plus default constructor parameters

Это не работает по очень разумным причинам:

class MyClass(field1: String = "foo", field2: String = "bar") { 
    def this() = { 
     this() // <-- Does not compile, but how do I not duplicate the defaults? 
    } 
} 

мне интересно, если есть что-то, что мне не хватает. Любые мысли, которые не требуют дублирования параметров по умолчанию?

Спасибо!

+1

есть билет на https://lampsvn.epfl.ch/trac/scala/ticket/4278 –

+1

Я высказался в пользу этого билета на моем первом в истории собрании scala и сказал, что мясо было уничтожено по хищному " не погубите язык своими особыми случаями «волки». Это для каждого случая для себя сейчас! – extempore

ответ

12

Я бы не рекомендовал его, но вы можете сделать это, добавив еще один параметр в конструкторе:

class MyClass(a: String = "foo", b: String = "bar", u: Unit =()) { 
    def this() { this(u =()) } 
} 

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

Если вы желаете реплицировать только один значений по умолчанию, вы можете использовать ту же стратегию, кроме переопределения того, что выбрали по умолчанию вместо добавления параметра единицы.

+0

Я согласен, что это в духе моего вопроса (сведение к минимуму дублирования), но не большая практика. Спасибо за ответ! – jkl

4

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

class MyClass(field1: String = "foo", field2: String = "bar") { 
    def this() = this(MyClass.init$default$1) 
} 

Обратите внимание, что это необходимо, чтобы включить MyClass в это (MyClass.init $ default $ 1). Частичное объяснение заключается в том, что аргументы по умолчанию хранятся в сопутствующих объектах.

4

Вы могли бы рассмотреть возможность использования фабричного метода:

class MyClass(field1: String = "foo", field2: String = "bar") 
object MyClass { 
    def newDefaultInstance = new MyClass 
} 

Тогда из Java вы можете позвонить MyClass.newDefaultInstance()

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

class MyClass(field1: String, field2: String) { 
    def this() = this(field1="foo", field2="bar") 
} 

Это стиль особенно полезен, если вы работаете с фреймворком, например Spring, который использует отражение, чтобы найти конструктор 0-arg.

+0

Спасибо за идеи.В моем конкретном случае первый не будет работать, так как это сервлет, который я инициализирую (так что мне нужен no-arg.) Второе возможно, но я теряю приятное поведение по умолчанию в тестах, которые были установлены по умолчанию , Я бы наверняка обратился к первому, если бы мне не нужен конструктор no-arg ... – jkl

0

Не подходит для всех целей, но подкласс может сделать трюк:

class DefaultMyClass extends MyClass() 
0

Если я не ошибаюсь в понимании вопроса, следующий код работает очень хорошо для me`

class Employee (

    ){ 
    def this(name :String , 

    eid :Int){ 
    this(); 
    } 
} 

`

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