Kotlin代码执行顺序疑问:字符串模板函数调用顺序解析
为什么Kotlin字符串模板中的函数调用会先于println的文本输出执行?
你的困惑完全可以理解——很多刚接触Kotlin(或者JVM系语言)的开发者都会误以为字符串模板是“边输出边插值”,但实际上这里的核心是函数实参的求值顺序规则。
我们来拆解你的代码执行的完整流程:
- 当执行
println("First ${foo()}, Second ${foo()}!")时,println是一个函数,它需要接收一个完整的字符串参数才能执行输出操作。 - 在调用
println函数之前,Kotlin必须先把这个带模板的字符串字面量完全构造出来,这就意味着所有${}包裹的表达式都要先被求值:- 首先求值第一个
${foo()}:调用foo()函数,输出Calculating foo...,得到返回值"foo" - 接着求值第二个
${foo()}:再次调用foo()函数,输出Calculating foo...,得到返回值"foo"
- 首先求值第一个
- 当所有模板表达式都求值完成后,完整的字符串
"First foo, Second foo!"被构造出来,这时才会调用println把这个字符串输出。
你的错误理解在于:你认为println会逐段输出字符串内容,遇到模板时才去调用函数,但实际上JVM语言遵循严格求值规则——函数的所有实参必须在函数被调用之前全部计算完毕,再传递给函数执行。
再举个更简单的例子验证这个规则:
fun bar(): Unit { println("bar 被调用了") } fun main() { println("开头 ${bar()} 结尾") }
执行结果会是:
bar 被调用了 开头 kotlin.Unit 结尾
可以看到,bar()是在println输出任何文本之前就执行了,这和你的例子是同一个逻辑。
内容的提问来源于stack exchange,提问作者Carlos Ortega
相关产品推荐
相关产品推荐

