henorek
henorek

Reputation: 502

Cleanest way to reassign the value of the variable when the condition is met in Kotlin

Let's say that I have Long variable which is decremented by some method. I want to set it to 60 after its decremented to 0. I tried apply function

  private var tempTime = interval.apply {
    if (this.equals(0L)) tempTime = interval
  }

but it's not even correct syntax.

tempTime is my variable which is gonna be decremented, interval is default value that I want to set after tempTime reach 0. Also, is there any way to avoid this ugly if equals 0L statement?

Upvotes: 2

Views: 2061

Answers (5)

miensol
miensol

Reputation: 41608

In Kotlin if statement is an expression therefore you can write:

var tempTime: Long = 60
...
val interval = 60L
tempTime = if (tempTime == 0L) {
    interval
} else {
    tempTime - 1
}

Upvotes: 3

voddan
voddan

Reputation: 33769

I don't think this is language specific. If you want to hide this behaviour, use the @jasonminard's answer. If your goal is to express it in the code, do what you would have done in C or Java or any other language:

var tempTime = 60L
val mod = (60 + 1)

// decrement:
tempTime = (tempTime - 1 + mod) % mod

Upvotes: 2

Sergey Tselovalnikov
Sergey Tselovalnikov

Reputation: 6036

You can use when. In my opinion, it looks cleaner.

var tempTime = 0L
val interval = 5L
tempTime = when (tempTime) {
    0L -> interval
    else -> tempTime
}

Upvotes: 2

Jayson Minard
Jayson Minard

Reputation: 85946

If you want to encapsulate this into a re-usable class:

class RepeatingInterval(val interval: Int, var current: Int = 0) {
    fun dec(): Int {
        current = if (current == 0) interval else current-1
        return current
    }
}

Then you can just:

val counter = RepeatingInterval(60)

// whenever you want to decrement it without worrying about it rolling over
val tempTime = counter.dec()

You can also add an inc() method to go the otherway with the interval:

class RepeatingInterval(val interval: Int, var current: Int = 0) {
    fun dec(): Int {
        current = if (current <= 0) interval else current-1
        return current
    }

    fun inc(): Int {
        current = if (current >= interval) 0 else current+1
        return current
    }
}

None of above is thread safe. If you want thread safe:

class RepeatingInterval(val interval: Int, starting: Int = 0) {
    val current = AtomicInteger(starting)

    fun dec(): Int {
        return current.accumulateAndGet(-1) { prev, x -> if (prev <= 0) interval else prev + x }
    }

    fun inc(): Int {
        return  current.accumulateAndGet(+1) { prev, x -> if (prev >= interval) 0 else prev + x }
    }
}

Upvotes: 0

wint
wint

Reputation: 1286

Using Backing Field

var tempTime = 0
    set(newValue) {
        if ( newValue < - 50 ) {
            field = 0
        } else {
            field = newValue
        }
    }

Using Backing Properties

private var _tempTime = 0
var tempTime: Int
    get() { return _tempTime }
    set(newValue) {
        if ( newValue < - 50 ) {
            _tempTime = 0
        } else {
            _tempTime = newValue
        }
    }

https://kotlinlang.org/docs/reference/properties.html

Upvotes: 0

Related Questions