2013-05-26 2 views
0

Я хочу проверить аргументы вторичного конструктора, но сначала я вынужден сначала вызвать первичный конструктор. Один из способов - поставить чеки внутри звонка на this, но он может стать уродливым, если условия сложны.Проверка аргументов вторичного конструктора

def this(initDollars: Int, initCents: Int) = { 
    this(if (initDollars >= 0 && initCents >= 0) initDollars * 100 + initCents else throw new Exception("Negative values")) 
    } 

Есть ли лучшие способы сделать это?

+1

Вы всегда можете проверить аргументы после вызова. В противном случае напишите функцию, которая проверит значения и либо выбросит исключение, либо вернет значение для перехода к второму конструктору: 'this (validateAndSum (initDollars, initCents))' –

+0

Мне очень нравится ваша идея, но она работает только если у нас есть один параметр – damluar

+1

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

ответ

1

Вы можете перенести код в метод в объект-компаньон, но почему бы не избежать конструкторов вместе и просто использовать объект-компаньон, когда вам нужна проверка?

object Example { // To keep class & companion together 
    class Foo private[Foo] (val value: Int) {} 
    object Foo { 
    def apply(i: Int) = if (i>=0) new Foo(i) else throw new Exception("Wrong") 
    def apply(i: Int, j: Int) = { 
     if (i>=0 && j>=0 && i.toLong*100+j < Int.MaxValue) new Foo(i*100+j) 
     else throw new Exception("Bleh") 
    } 
    } 
} 

Который работает следующим образом:

scala> Example.Foo(-47) 
java.lang.Exception: Wrong 
    at Example$Foo$.apply(<console>:15) 
     [...] 

scala> Example.Foo(49,62) 
res19: Example.Foo = [email protected] 

scala> res19.value 
res20: Int = 4962 

(В коде не его REPL, вам не нужно обернуть в Example для них, чтобы быть компаньоном объекты, просто их в одном файле Или вы можете использовать^D в REPL.)

2

Почему бы не сначала вызвать первичный конструктор и не проверить позже? Результат тот же.

def this(initDollars: Int, initCents: Int) = { 
    this(initDollars * 100 + initCents) 
    assert(initDollars >= 0 && initCents >= 0, "Negative values") 
} 

Альтернативой может быть спутником объект с apply -метода.

+0

просто для экономии времени на вычислениях, например – damluar

+0

Серьезно? Я бы предпочел иметь читаемый код, чем некоторые сохраненные наносекунды. – Landei

+0

Кроме того, проверка в конструкторе 'primary' гарантирует, что ваши предварительные условия всегда выполняются, даже если он вызывается из let say say apply метод' companion' object ... – Shrey

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