如何检测函数参数值是输入还是默认值

问题描述 投票:0回答:1

将函数定义为

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

kotlin reflection
1个回答
0
投票

首先,函数参数之前不允许使用

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
中读取不想触及的值,并将它们与新值一起传递给函数。

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.