跳到内容

%N 用于名称

生成代码通常是自引用的。使用 %N 按名称引用另一个生成的声明。这里有一个调用另一个方法的方法

fun byteToHex(b: Int): String {
  val result = CharArray(2)
  result[0] = hexDigit((b ushr 4) and 0xf)
  result[1] = hexDigit(b and 0xf)
  return String(result)
}

fun hexDigit(i: Int): Char {
  return (if (i < 10) i + '0'.toInt() else i - 10 + 'a'.toInt()).toChar()
}

生成上述代码时,我们使用 %NhexDigit() 方法作为参数传递给 byteToHex() 方法

val hexDigit = FunSpec.builder("hexDigit")
  .addParameter("i", Int::class)
  .returns(Char::class)
  .addStatement("return (if (i < 10) i + '0'.toInt() else i - 10 + 'a'.toInt()).toChar()")
  .build()

val byteToHex = FunSpec.builder("byteToHex")
  .addParameter("b", Int::class)
  .returns(String::class)
  .addStatement("val result = CharArray(2)")
  .addStatement("result[0] = %N((b ushr 4) and 0xf)", hexDigit)
  .addStatement("result[1] = %N(b and 0xf)", hexDigit)
  .addStatement("return String(result)")
  .build()

%N 的另一个方便之处在于它会自动用双反引号转义包含非法标识符字符的名称。假设您的代码创建了一个使用 Kotlin 关键字作为简单名称的 MemberName

val taco = ClassName("com.squareup.tacos", "Taco")
val packager = ClassName("com.squareup.tacos", "TacoPackager")
val file = FileSpec.builder("com.example", "Test")
  .addFunction(
    FunSpec.builder("packageTacos")
      .addParameter("tacos", LIST.parameterizedBy(taco))
      .addParameter("packager", packager)
      .addStatement("packager.%N(tacos)", packager.member("package"))
      .build()
  )
  .build()

%N 会为您转义名称,确保输出通过编译

package com.example

import com.squareup.tacos.Taco
import com.squareup.tacos.TacoPackager
import kotlin.collections.List

fun packageTacos(tacos: List<Taco>, packager: TacoPackager) {
  packager.`package`(tacos)
}