Как динамически определить блок кода с параметрами

Я застрял в этой функции, ниже приведен ожидаемый код, который будет сгенерирован, и общее количество параметров не является фиксированным числом, может быть 2, 3 или более.

val instance: InstanceType = Instance (параметр1, параметр2)

это внутри одной функции, поэтому я знаю только, что должен использовать.addCode(CodeBlock.of("%L", PropertySpec))

Но я не нахожу способ определить блок кода с динамическими параметрами, которые необходимо передать. Любое предложение?

1 ответ

Есть два способа решить это. Первый, 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())
}
Другие вопросы по тегам