将函数定义为
fun foo(
bar: String? = null
) { ... }
如何知道
bar
是 null
是因为没有传递值还是因为传递了 null
? IE。该函数被称为 foo()
或 foo(bar = null)
?
实际案例:
data class State(
val foo: String? = null,
val bar: Int? = null,
val baz: Long? = null,
)
class StateManager {
var state: State
private set
fun setState(
val foo: String? = null,
val bar: Int? = null,
val baz: Long? = null,
) {
state = state.copy(foo, bar, baz)
}
}
此示例不起作用,因为
setState(bar = 1)
覆盖了 null
foo
和 baz
变量。相反,state.copy(bar = 1)
不会覆盖 foo
和 baz
。我假设 copy
的实现能够区分 null
是作为参数提供还是默认值。
我得到的最好的:
fun setState(
val foo: String? = null,
val bar: Int? = null,
val baz: Long? = null,
) {
val copyRef = state::copy
val params = copyRef.parameters
val values = mutableMapOf<KParameter, Any?>()
if (foo != null) values[params[0]] = foo
if (bar != null) values[params[1]] = bar
if (baz != null) values[params[2]] = baz
state = copyRef.callBy(values)
}
此解决方案不会覆盖
null
未指定的值,但无法在需要时分配 null
。
首先,函数参数之前不允许使用
val/var
。我猜它们是您帖子中的复制粘贴错误。
我不知道你的确切用例,但很可能,你可以用不同的方式设计它。
重点关注您所描述的问题,从
setState()
函数的所有参数中删除默认值怎么样?
fun setState(foo: String?, bar:Int?, baz:Long?){
state = State(foo, bar, baz) //or copy(...), if you love that way
}
当您调用
setState()
时,假设您想使用当前 bar
中的 state
,并使用新值重置 foo
,并将 baz
设为 null
:
setState(newFoo, state.bar, null)
通过这种方式,您可以从当前
state
中读取不想触及的值,并将它们与新值一起传递给函数。
希望有帮助。