0

This might be a bit too specific for posting here, but I'm trying to generate a class like this with kotlinpoet:

class Query<out E: Model>(val onSuccess: (E) -> Unit, val onError: (Int, String) -> Unit = { i, m -> })

How would I create that type/constructor parameter with kotlinpoet? The docs do have the "Unit" type listed along with primitive types, so it seems to be a special case.

4

2 回答 2

1

这是一个产生您需要的输出的程序:

class Model

fun main(args: Array<String>) {
  val onSuccessType = LambdaTypeName.get(
      parameters = TypeVariableName(name = "E"),
      returnType = Unit::class.asTypeName())
  val onErrorType = LambdaTypeName.get(
      parameters = listOf(Int::class.asTypeName(), String::class.asTypeName()),
      returnType = Unit::class.asTypeName())
  val primaryConstructor = FunSpec.constructorBuilder()
      .addParameter(ParameterSpec.builder(name = "onSuccess", type = onSuccessType)
          .build())
      .addParameter(ParameterSpec.builder(name = "onError", type = onErrorType)
          .defaultValue("{ i, m -> }")
          .build())
      .build()

  val querySpec = TypeSpec.classBuilder("Query")
      .addTypeVariable(TypeVariableName(name = "out E", bounds = Model::class))
      .addProperty(PropertySpec.builder(name = "onSuccess", type = onSuccessType)
          .initializer("onSuccess")
          .build())
      .addProperty(PropertySpec.builder(name = "onError", type = onErrorType)
          .initializer("onError")
          .build())
      .primaryConstructor(primaryConstructor)
      .build()

  val file = KotlinFile.builder(packageName = "", fileName = "test")
      .addType(querySpec)
      .build()
  file.writeTo(System.out)
}

这将打印(不包括生成的导入)以下内容:

class Query<out E : Model>(val onSuccess: (E) -> Unit,
    val onError: (Int, String) -> Unit = { i, m -> })

我在TypeVariableName这里进行黑客攻击out E,因为当时似乎没有更好的解决方案。我也在用这个0.4.0-SNAPSHOT版本。

于 2017-08-03T07:24:55.553 回答
0

很容易,它是通过使用LambdaTypeName类来完成的。在习惯了 kotlin 的函数类型风格而不是 java 严格的函数接口之后,这有点令人困惑。这是我使用的:

val typeVariable = TypeVariableName.invoke("E")
    .withBounds(QueryData::class)
ParameterSpec.builder("onSuccess", 
    LambdaTypeName.get(null, listOf(typeVariable), UNIT)).build()

生成(当然是类构建器):

class Query<E : QueryData> {
  constructor(onSuccess: (E) -> Unit) {
  }
}
于 2017-08-02T00:30:15.803 回答