Как отличить явный ноль от пропущенного параметра - PullRequest
0 голосов
/ 05 июня 2018

Я хотел бы добиться чего-то подобного, в основном отличить пропущенный параметр от явно установленного как null:

sealed class Expr
data class HasValue<out T>(val value: T)
object IsNull: Expr()

/* inside a class */
fun filter(v1: Expr<Int>? = null, v2: Expr<String>? = null): Collection<T> {
    when (v1) {
        is HasValue -> /* Filter collection elements that have some attr set to given value */
        is IsNull -> /* filter collection elements that have some attr set to null */
        is null -> /* do nothing, return all elements */
    }

    when (v2) /* so on */
}

/* call site */
myObj.filter(v1=IsNull<Int>(), v2=HasValue<String>("string"))

РЕДАКТИРОВАТЬ:

Рабочаярешение:

sealed class Expr<out T> {
    abstract val value: T?
}
data class WithValue<out T>(override val value: T?) : Expr<T>()

/* usage */
fun filter(v1: Expr<Int>? = null) {
    when (v1) {
        is WithValue -> println(if ((v1.value ?: 0) > 10) "10 and above" else "less") /* Type safe, explicit null handling */
        null -> println("isNull") /* parameter was omitted */
    }
}
filter(WithValue<Int>(null)) /* will match explicit null elements */
filter() /* will ignore v1 from filtering */

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Есть несколько проблем с предоставленным кодом, в основном с дженериками.Но я думаю, что главное, что вы задавали в этих вопросах, было исчерпывающим when.Если вы хотите сопоставить по типу, вы пишете

  • is SomeClass для классов
  • Object для объектов
  • null для нуля

Итак, ваш when должен выглядеть так:

when (v1) {
    is HasValue<*> -> /* Filter collection elements that have some attr set to given value */
    IsNull -> /* filter collection elements that have some attr set to null */
    null -> /* do nothing, return all elements */
}

и весь код:

sealed class Expr {
    data class HasValue<out T>(val value: T) : Expr()
    object IsNull: Expr()
}

private fun <T> filter(v1: Expr? = null, v2: Expr? = null): Collection<T> {
    when (v1) {
        is HasValue<*> -> /* Filter collection elements that have some attr set to given value */
        IsNull -> /* filter collection elements that have some attr set to null */
        null -> /* do nothing, return all elements */
    }
    // matching with v2
}

/* call site */
filter<Int>(v1=IsNull, v2=HasValue("string"))
0 голосов
/ 05 июня 2018

Что вы можете сделать, не используя null, но пользовательский частный экземпляр, например:

/* inside a class */
private val EMPTY = Expr()
fun filter(v1: Expr<Int>? = EMPTY, v2: Expr<String>? = EMPTY): Collection<T> {
    if (v1 === EMPTY) {
        // parameter not defined by user
    } else {
        // parameter defined by user
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...