Kotlin 如何为属性定义这些复杂的初始值设定项
虽然我检查了kotlinpoet代码中的所有测试,但我没有找到实现低于目标代码的正确方法,或者我不确定是否使用了最好的方法。如果有人能对此提出一些意见,我们将不胜感激 这些属性是在类的函数中定义的 目标代码1Kotlin 如何为属性定义这些复杂的初始值设定项,kotlin,kotlinpoet,Kotlin,Kotlinpoet,虽然我检查了kotlinpoet代码中的所有测试,但我没有找到实现低于目标代码的正确方法,或者我不确定是否使用了最好的方法。如果有人能对此提出一些意见,我们将不胜感激 这些属性是在类的函数中定义的 目标代码1 val outputState = StateType1(iouValue, ourIdentity, otherParty) 我使用下面的代码来生成上面的代码 .addCode(CodeBlock.of("%L", PropertySpec.builder("outputSta
val outputState = StateType1(iouValue, ourIdentity, otherParty)
我使用下面的代码来生成上面的代码
.addCode(CodeBlock.of("%L",
PropertySpec.builder("outputState", ClassName("","StateType1"))
.initializer(CodeBlock.of("%T(%L, %L, %L)", ClassName("","StateType1"), "iouValue", "ourIdentity", "otherParty"))
.build()))
但问题是这个outputState可能来自不同的类型,例如,StateType1有3个参数,而StateType2可能只有1个参数,我应该如何动态定义我的KotInput代码来生成正确的目标代码
目标代码2
val txBuilder = TransactionBuilder(notary = notary)
.addOutputState(outputState, TEMPLATE_CONTRACT_ID)
我没有找到一个具有这种情况的参考测试用例,在属性的初始值设定项之后,直接调用它的函数。使用
CodeBlock.Builder
对于第一个示例,它在构造CodeBlock
s时为您提供了更大的灵活性:
fun createConstructorCall(type: TypeName, vararg args: String): CodeBlock {
val argsCode = args
.map { CodeBlock.of("%L", it) }
.joinToCode(separator = ", ", prefix = "(", suffix = ")")
return CodeBlock.Builder()
.add("%T", type)
.add(argsCode)
.build()
}
val className = ClassName("", "StateType1")
val codeBlock = CodeBlock.of("%L", PropertySpec.builder("outputState", className)
.initializer(createConstructorCall(className, "iouValue", "ourIdentity", "otherParty"))
.build())
assertThat(codeBlock.toString()).isEqualTo("""
|val outputState: StateType1 = StateType1(iouValue, ourIdentity, otherParty)
|""".trimMargin())
在第二个示例中,我们没有提供任何特殊的内容,将代码作为字符串传递,如果需要,可以随意使用占位符进行参数化:
val className1 = ClassName("", "TransactionBuilder")
val codeBlock1 = CodeBlock.of("%L", PropertySpec.builder("txBuilder", className)
.initializer(
"%T(notary = notary)\n.addOutputState(outputState, TEMPLATE_CONTRACT_ID)",
className1)
.build())
assertThat(codeBlock1.toString()).isEqualTo("""
|val txBuilder: StateType1 = TransactionBuilder(notary = notary)
| .addOutputState(outputState, TEMPLATE_CONTRACT_ID)
|""".trimMargin())