What is the right way of using “greater than”, “less than” comparison on nullable integers in Kotlin?

前端 未结 6 1701
南方客
南方客 2021-01-03 19:00
var _age: Int? = 0

public var isAdult: Boolean? = false
   get() = _age?.compareTo(18) >= 0 

This still gives me a null-safety, compile error,

相关标签:
6条回答
  • 2021-01-03 19:37

    A generic and flexible solution would be:

    infix fun <T : Comparable<T>> T?.isGreaterThan(other: T?): Boolean? =
        if (this != null && other != null) this > other else null
    
    infix fun <T : Comparable<T>> T?.isGreaterThanOrEqual(other: T?): Boolean? =
        if (this != null && other != null) this >= other else null
    
    infix fun <T : Comparable<T>> T?.isLessThan(other: T?): Boolean? =
        if (this != null && other != null) this < other else null
    
    infix fun <T : Comparable<T>> T?.isLessThanOrEqual(other: T?): Boolean? =
        if (this != null && other != null) this <= other else null
    
    

    Depending on your needs, you could use it as:

    public var isAdult: Boolean? = false
        get() = _age isGreaterThanOrEqual 18
    

    or:

    public var isAdult: Boolean = false
        get() = _age isGreaterThanOrEqual 18 == true
    
    0 讨论(0)
  • 2021-01-03 19:47
    var age : Int? = 0
    
    public val isAdult : Boolean?
        get() = age?.let { it >= 18 }
    

    The other solution would be using delegates:

    var age : Int by Delegates.notNull()
    public val isAdult : Boolean
        get () = age >= 18
    

    So if you try to get age or check isAdult before age was actually assigned then you'll get exception instead of null.

    Anyway I believe age = 0 is some kind magic that one day may lead to issue (even prod issue).

    0 讨论(0)
  • 2021-01-03 19:47

    I used the null coalescing operator to convert from nullable Int? to non-nullable Int:

    var age: Int? = 0
    
    public var isAdult: Boolean? = null
       get() = if(age == null) null else (age ?: 0 >= 18)
    
    0 讨论(0)
  • 2021-01-03 19:49

    Kotlin could sure use an extension function on Int for this, but until they do:

    fun Int?.isGreaterThan(other: Int?) =
        this != null && other != null && this > other
    
    fun Int?.isLessThan(other: Int?) =
        this != null && other != null && this < other
    

    My methods returns false, not null if either operand is null. That makes more sense to me.

    0 讨论(0)
  • 2021-01-03 19:55

    You could possibly use the built-in function compareValue:

    fun <T : Comparable<*>> compareValues(a: T?, b: T?): Int
    
    public var isAdult: Boolean = false
       get() = compareValues(_age, 18) >= 0
    

    or

    public var isAdult: Boolean = false
       get() = compareValues(18, _age) <= 0
    

    Note however that null is considered less than any value, which may suit your case, but may lead to undesired behavior in other cases. E.g., think of var grantMinorsDiscount.

    0 讨论(0)
  • 2021-01-03 19:59

    Also can try this:

    var position = 100
    
        mArrayList?.let {
    
                    if (it.size > 0 && position >= 0 ) 
                         return true
    
                }
    
    0 讨论(0)
提交回复
热议问题