我想实现这样的目标,基本上将省略的参数与显式设置为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 */
答案 0 :(得分:0)
你可以做什么,而不是使用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
}
}
答案 1 :(得分:0)
提供的代码存在一些问题,主要是泛型。但我认为问题的主要内容是详尽when
。如果你想按类型匹配,你可以写
is SomeClass
用于课程Object
对象null
for 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"))