Как сгенерировать параметр конструктора типа Kotlin "Unit" с параметром одного типа с помощью kotlinpoet?
Это может быть слишком специфично для публикации здесь, но я пытаюсь создать такой класс с помощью kotlinpoet:
class Query<out E: Model>(val onSuccess: (E) -> Unit, val onError: (Int, String) -> Unit = { i, m -> })
Как бы я создал этот параметр типа / конструктора с kotlinpoet? Документы имеют "Unit
"Тип перечислен вместе с примитивными типами, поэтому, похоже, это особый случай.
2 ответа
Достаточно легко, это делается с помощью 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) {
}
}
Вот программа, которая производит вывод, который вам нужен:
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
версия.