首页 > 解决方案 > 如何动态定义带参数的代码块

问题描述

我被这个特性卡住了,下面是要生成的预期代码,参数的总数不是一个固定的数字,可能有 2 个,或者 3 个或更多。

val 实例:InstanceType = Instance(parameter1, parameter2)

这是在一个函数中,所以我只知道我应该使用 .addCode(CodeBlock.of("%L", PropertySpec))

但是我没有找到一种方法来定义需要传入动态参数的代码块。有什么建议吗?

标签: kotlinpoet

解决方案


有两种方法可以解决这个问题。首先,CodeBlock有一个Builder允许您动态构建它。这是一个例子:

@Test fun manyParams() {
  val instanceType = ClassName("", "InstanceType")
  val instance = ClassName("", "Instance")
  val params = listOf("param1", "param2")
  val prop = PropertySpec.builder("instance", instanceType)
      .initializer(CodeBlock.builder()
          .add("%T(", instance)
          .apply {
            params.forEachIndexed { index, param ->
              if (index > 0) add(",%W")
              add(param)
            }
          }
          .add(")")
          .build())
      .build()

  assertThat(prop.toString()).isEqualTo("""
    |val instance: InstanceType = Instance(param1, param2)
    |""".trimMargin())
}

其次,您可以为每个参数创建一个单独CodeBlock的参数并加入它们:

@Test fun manyParams() {
  val instanceType = ClassName("", "InstanceType")
  val instance = ClassName("", "Instance")
  val params = listOf("param1", "param2")
  val paramCodeBlocks = params.map { CodeBlock.of(it) }
  val prop = PropertySpec.builder("instance", instanceType)
      .initializer("%T(%L)", instance, paramCodeBlocks.joinToCode(separator = ",%W"))
      .build()

  assertThat(prop.toString()).isEqualTo("""
    |val instance: InstanceType = Instance(param1, param2)
    |""".trimMargin())
}

推荐阅读