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

Time:07-22

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

CodePudding user response:

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
        }
    }
}

CodePudding user response:

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!

  • Related