如何在Kotlin字符串模板中嵌入循环

我们可以像在Kotlin字符串模板中一样简单地嵌套表达式运算符:

 "List ${if (list.isEmpty()) "is empty" else "has ${list.size} items"}." 

但是for或不是表达式,不能像这样嵌套在模板中:

 "<ol>${for (item in list) "<li>$item"}</ol>" 

所以我正在寻找方便的方式来使用大模板内的循环。

到目前为止我发现的最简单的开箱即用的方法是用等效的joinToString调用替换循环:

 "<ol>${list.joinToString("") { "<li>$it" }}</ol>" 

要么

 """ <ol>${list.indices.joinToString("") { """ <li id="item${it + 1}">${list[it]}""" }} </ol>""".trimIndent() 

在喜好的情况下,也可以用辅助函数来模拟循环:

 inline fun <T> forEach(iterable: Iterable<T>, crossinline out: (v: T) -> String) = iterable.joinToString("") { out(it) } fun <T> forEachIndexed1(iterable: Iterable<T>, out: (i: Int, v: T) -> String): String { val sb = StringBuilder() iterable.forEachIndexed { i, it -> sb.append(out(i + 1, it)) } return sb.toString() } 

并像这样使用它们:

 "<ol>${forEach(list) { "<li>$it" }}</ol>" 

要么

 """ <ol>${forEachIndexed1(list) { i, item -> """ <li id="item$i">$item""" }} </ol>""".trimIndent() 

你可以简单地使用joinToString来代替。

 val s = """<ol> ${list.joinToString { "<li>$it</li>" }} </ol>"""; 

产量

 <ol> <li>one</li> <li>two</li> ... </ol>