属性¶
与参数类似,属性既可以通过构建器创建,也可以使用便捷的辅助方法创建
val android = PropertySpec.builder("android", String::class)
.addModifiers(KModifier.PRIVATE)
.build()
val helloWorld = TypeSpec.classBuilder("HelloWorld")
.addProperty(android)
.addProperty("robot", String::class, KModifier.PRIVATE)
.build()
生成以下代码
class HelloWorld {
private val android: String
private val robot: String
}
当字段包含 KDoc、注解或字段初始化器时,需要使用扩展的 Builder
形式。字段初始化器使用与上述代码块相同的类似 String.format()
的语法
val android = PropertySpec.builder("android", String::class)
.addModifiers(KModifier.PRIVATE)
.initializer("%S + %L", "Oreo v.", 8.1)
.build()
生成以下代码
private val android: String = "Oreo v." + 8.1
默认情况下,PropertySpec.Builder
会生成 val
属性。如果你需要 var
,请使用 mutable()
val android = PropertySpec.builder("android", String::class)
.mutable()
.addModifiers(KModifier.PRIVATE)
.initializer("%S + %L", "Oreo v.", 8.1)
.build()
内联属性¶
KotlinPoet 建模内联属性的方式值得特别提及。以下代码片段
val android = PropertySpec.builder("android", String::class)
.mutable()
.addModifiers(KModifier.INLINE)
.build()
将产生错误
java.lang.IllegalArgumentException: KotlinPoet doesn't allow setting the inline modifier on
properties. You should mark either the getter, the setter, or both inline.
确实,标记为 inline
的属性应至少包含一个访问器,该访问器将被编译器内联。让我们为该属性添加一个 getter
val android = PropertySpec.builder("android", String::class)
.mutable()
.getter(
FunSpec.getterBuilder()
.addModifiers(KModifier.INLINE)
.addStatement("return %S", "foo")
.build()
)
.build()
结果如下
var android: kotlin.String
inline get() = "foo"
现在,如果我们想为上面的属性添加一个非内联的 setter 呢?我们可以这样做,而无需修改之前编写的任何代码
val android = PropertySpec.builder("android", String::class)
.mutable()
.getter(
FunSpec.getterBuilder()
.addModifiers(KModifier.INLINE)
.addStatement("return %S", "foo")
.build()
)
.setter(
FunSpec.setterBuilder()
.addParameter("value", String::class)
.build()
)
.build()
我们得到了预期的结果
var android: kotlin.String
inline get() = "foo"
set(`value`) {
}
最后,如果我们返回并为 setter 添加 KModifier.INLINE
,KotlinPoet 可以很好地包装它并产生以下结果
inline var android: kotlin.String
get() = "foo"
set(`value`) {
}
从 getter 或 setter 中移除修饰符将解开表达式。
另一方面,如果 KotlinPoet 允许直接将属性标记为 inline
,那么每当访问器的状态发生变化时,程序员就必须手动添加/移除修饰符,以获得正确且可编译的输出。我们通过将访问器作为 inline
修饰符的真相源来解决这个问题。