Hi Everybody! .. I'm just doing my first steps in ...
# getting-started
j
Hi Everybody! .. I'm just doing my first steps in Kotlin after a long time using Groovy, so far I'm enjoying it. I have a question, probably simple but Im trying to get some traction. -> If I have an app which is using BigDecimal heavily, is there a way to avoid creating theBigDecimal explicitly when calling methods that expect a BigDecimal? (something like implicit transformation from integer to BigDecimal on the caller so you can call methods using just a integer) E.g. When instantiating this data class, I have to pass the salary as explicit integer:
Copy code
val employeeRunData = EmployeeRunData(annualSalary = BigDecimal(120000))
Instead, I would like to do something like: <note there is not call to _BigDecimal(120000)_>
Copy code
val employeeRunData = EmployeeRunData(annualSalary = 120000))
I would highlight that the annoyance is while writing unit test. Thank you all!
m
there is no implicit conversion, but you can always do
Copy code
fun EmployeeRunData(annualSalary: Int) = EmployeeRunData(annualSalary = BigDecimal(annualSalary))
m
secondary constructors are probably what you need:
Copy code
fun main(){
    val constructWithBigDecimal = EmployeeRunData(BigDecimal.TEN)
    val constructWithNumber = EmployeeRunData(2341L)
}

data class EmployeeRunData(val annualSalary: BigDecimal) {
    constructor(annualSalary: Number) : this(BigDecimal(annualSalary.toString()))
}
This way, whenever you call the constructor of EmployeeRunData, it will set its annualSalary directly if you call it with a BigDecimal, otherwise it will call it with the constructor. If your problem is in writing unittests only, I suggest just making local functions
m
previously, in another language, I used extension methods to make this a bit easier. So if
foo()
expects a BigDecimal, you could call it like
foo(<http://123.bd|123.bd>)
🤔 1
e
That’s what I’d recommend:
Copy code
val <http://Int.bd|Int.bd> get() = toBigDecimal()
🤔 1
1
j
Thanks all for the answers. I’m trying to avoid secondary constructors because I want the production contract to be only with BigDecimal. I think that @Martin and @elizarov answers are what I’m looking for. Roman/Martin Could you provide some context/explanation to help me to understand the solution? ; my initial read from this is that we are creating a extension function to a property called “bd” that call a method toBigDecimal() which needs to be implemented. Is it correct? Thanks for the help!
m
The Kotlin standard library already defines
toBigDecimal()
as an extension function on the
Int
type, so you don't need to implement that. @elizarov's solution is adding a
bd
property to the
Int
type, and the getter for that property delegates to
toBigDecimal()
. That way,
EmployeeRunData
only needs the primary constructor, which takes a
BigDecimal
, and you can call it like:
val constructWithBigDecimal = EmployeeRunData(<http://10.bd|10.bd>)
. Does that make more sense?
👍 1
💯 1
j
Thanks a lot @Martin . It makes sense!!
👍 1