indee423
indee423

Reputation: 481

Is there a way to make the first digit of int always start with 1 in Kotlin

Let's say I have the following class constructor:

class Car(val brand: Brand,val modelName: String, val version: Int){} 

If for example, I want the version number to always start with 1. Is there a way to manipulate it in the class body to achieve this ?

Meaning:

val firstdigit:Int = abs(version).ToString().Substring(0,1)

And then parse it to Int. But how to replace the original first digit after that? I'm just learning Kotlin and I got a bit stuck with this

Upvotes: 0

Views: 341

Answers (2)

cactustictacs
cactustictacs

Reputation: 19544

You already said in the comments that you want the number to increment per instance, so the caller shouldn't be providing that number in the first place really! But just generally, here's two approaches to sanitising your input parameters:

1) Make it the caller's responsibility to provide valid data

init {
    require(version.toString().first() == '1') { "Needs to start with 1 thanks" }
}

require throws an IllegalArgumentException if it fails, which is the standard exception for "the value of this argument is invalid". Should the class be responsible for taking bad data and trying to "fix" it, or should the caller be handling that - and maybe not constructing an instance at all if it doesn't have valid data?

2. create a newInstance function that uses valid data, and keep the constructor private

class Thing private constructor(val number: Int){
    companion object {
        fun newInstance(num: Int): Thing {
            return Thing(abs(num))
        }
    }
}

fun main() {
    Thing.newInstance(-2).let { println(it.number)}
}

If it makes sense for the class itself to sanitise the input parameters, you can delegate construction to a function that takes care of that, and prevent things from calling the constructor directly with potentially bad data.

This can cause issues with e.g. serialisation libraries (which want to call the constructor directly) but in that case you could leave the constructor public, and just advise callers to call newInstance instead. Not ideal, but it's an option!

Upvotes: 1

Ruckus T-Boom
Ruckus T-Boom

Reputation: 4796

Is this what you had in mind?

class Car(val brand: Brand, val modelName: String) {
    val version = getNextVersion()
    
    companion object {
        private var nextVersion = 0
        
        private fun getNextVersion(): Int {
            nextVersion++
            if (nextVersion.toString()[0] != '1') {
                nextVersion = (10.0.pow(ceil(log10(nextVersion.toDouble())))).toInt()
            }
            return nextVersion
        }
    }
}

Upvotes: 2

Related Questions