是否有一种优雅的方法可以将可空类型分配给可选参数?

时间:2018-10-16 16:15:50

标签: kotlin

我具有以下功能:

fun leftPad(value: String, length: Int = 3, char: Char = ' '): String = value.padStart(length, char)

是否有一种方法可以调用此方法,并将具有可空类型的值传递给可选参数,如:

length: Int? = getLength()
char: Char? = getChar()
leftPad(value, length = length, char = char)

我尝试过的唯一解决方法如下:

fun leftPad(value: String, length: Int? = null, char: Char? = null): String {
        val length = length ?: 4
        val char = char ?: ' '
        return value.padStart(length, char)
    }

它确实可以满足我的要求,但是这个名称笼罩着警告,让我有些不适。

2 个答案:

答案 0 :(得分:3)

阴影阴影警告仅表示您的val length阴影了方法中的length参数。要消除它,可以内联默认值或重命名本地变量。例如:

fun leftPad(value: String, length: Int? = null, char: Char? = null): String {
    return value.padStart(length ?: 4, char ?: ' ')
}

fun leftPad(value: String, length: Int? = null, char: Char? = null): String {
    val resolvedLength = length ?: 4
    val resolvedChar = char ?: ' '
    return value.padStart(resolvedLength, resolvedChar)
}

答案 1 :(得分:0)

这取决于您对优雅的定义,但可以通过反射来做些事情。

以下是将参数映射应用于主构造函数的方法(construct),也是在应用映射之前过滤出constructNullIsDefault值的第二种方法(null) (以及一些带有Pair变量的语法糖,以避免必须为每次调用自己构建Map)

inline fun <reified X : Any> constructNullIsDefault(vararg arguments: Pair<String, Any?>): X? {
    return construct(arguments.toMap().filterValues { it != null } as Map<String, Any>)
}

inline fun <reified X : Any> construct(arguments: Map<String, Any>): X? {
    val klass = X::class
    val constructor = klass.primaryConstructor!!
    val parameters = constructor.parameters
    val parameterMap =
        arguments.map { argument -> parameters.find { it.name == argument.key }!! to argument.value }.toMap()
    return constructor.callBy(parameterMap)
}

@Test
fun testAbc() {
    val x = "hello"
    val y = null as String?

    val abc = constructNullIsDefault<Abc>("x" to x, "y" to y)
    println(abc)
}