这是我参与更文挑战的第 30 天,活动详情查看: 更文挑战
最近在 portal.kotlin-academy.com/#/ 上看到很多关于 Kotlin 的有趣的题目。个人觉得很适合 Kotlin 爱好者,感兴趣的小伙伴可自行查阅。 【有趣的 Kotlin 】系列记录自己对每一题的理解。
0x02:Indent trimming
fun main(args: Array<String>) {
val world = "multiline world"
println("""
Hello
\$world
""".trimIndent())
}
以上代码,运行结果是什么?可选项:
- Hello $world
- Hello $world
- Hello \multiline world
- doesn't compile
思考一下,记录下你心中的答案。
分析
- Kotlin 中的 Raw String 是用
"""
三个双引号包裹的; - Kotlin 中的 Raw String 包含非转义字符、新行符,以及其它任意字符。也就是说,题中的
\
转义字符会被当成普通字符处理; $
符号表示处理字符串模板表达式;trimIndent()
会检测所有输入行的通用最小缩进,将其从每一行中删除。
经过上述分析,题目转义字符失效,字符串模板替换 world
变量,再结合trimIndent
函数去掉缩进,答案很明显为
选项3:
Hello
\multiline world
总结
转义字符串
Kotlin 中我们常用的字符串基本都是用 "
单个双引号包裹的转移字符串。
支持转义字符,也支持字符串模板表达式 ,表达式运行结果拼接至字符串内表达式所在位置。
例如:
val love = "OpenCV \nor Android"
println("I Love $love")
println("I Love \$love")
运行结果就是:
I Love OpenCV
or Android
I Love $love
原始字符串
Kotlin 中被 """
三个双引号包裹的内容为原始字符串(Raw String),不支持转义字符,支持字符串模板表达式。
例如:
val love = "OpenCV \nor Android"
println("""I Love $love""")
println("""I Love \$love""")
运行结果如下:
I Love OpenCV
or Android
I Love \OpenCV
or Android
在看看 trim()
、 trimIndent()
、trimMargin()
val spaceTrim = """
Yes
No
Other
""".trim()
println(spaceTrim)
val spaceTrimMargin = """
Yes
No
Other
""".trimMargin()
println(spaceTrimMargin)
val spaceTrimIndent = """
Yes
No
Other
""".trimIndent()
println(spaceTrimIndent)
运行结果如下:
把 trimMargin()
拿出来单独看看,源码如下:
public fun String.trimMargin(marginPrefix: String = "|"): String =
replaceIndentByMargin("", marginPrefix)
参数 marginPrefix
默认参数为|
。将其作为边界字符,方便原始字符串整理对齐。具体看下面几个例子:
val marginOne = """
|Yes
|No
|Other
""".trimMargin()
println(marginOne)
val marginTwo = """
>Yes
>No
>Other
""".trimMargin()
println(marginTwo)
val marginThree = """
>Yes
>No
>Other
""".trimMargin(">")
println(marginThree)
运行结果如下:
Yes
No
Other
>Yes
>No
>Other
Yes
No
Other