表达式以意想不到的顺序打印

时间:2013-12-18 14:38:36

标签: scala

当我打印这样的日志信息时:

val idList = getIdList
log info s"\n\n-------idList: ${idList foreach println}"

它告诉我:

1
2
3
4
5
-------idList: () 

这是有道理的,因为foreach会返回Unit。但为什么它首先打印id列表? idList已经在上一行中进行了评估(如果这是原因)!

如何让它按预期顺序打印 - 在idList:之后?

4 个答案:

答案 0 :(得分:5)

这是因为您没有评估日志字符串以读取您想要的内容,而是将其评估为:

\n\n    -------idList: ()

但是,由于字符串插值中的println调用,列表成员在输出流中显示为副作用。


编辑:,因为OP要求澄清, 输出来自两个来源

  1. ${idList foreach println}评估为(),因为println 本身不会返回任何内容。
  2. 然而,您可以看到打印出来的元素,因为在评估字符串插值时,正在调用println 。并且println将所有元素打印到输出流中。
  3. 换句话说:

    //line with log.info() reached, starts evaluating string before method call
    1 //println from foreach
    2 //println from foreach
    3 //println from foreach
    4 //println from foreach
    5 //println from foreach
    //string argument log.info() evaluated from interpolation
    -------idList: () //log info prints the resultant string
    

    要解决您的问题,修改插值字符串中的表达式以实际返回正确的字符串,例如:

    log info s"\n\n-------idList: ${idList.mkString("\n")}"
    

答案 1 :(得分:1)

插值以下列方式工作:

  1. 评估所有参数
  2. 将结果替换为结果字符串

答案 2 :(得分:0)

println是打印到标准输出的Unit函数,你应该使用mkstring来返回一个字符串

log info s"\n\n-------idList: ${idList.mkString("(", ", ", ")")}"

答案 3 :(得分:0)

正如@TheTerribleSwiftTomato所指出的,你需要给出一个表达式,它返回一个值并且没有其他副作用。所以简单地这样做:

val idList = getIdList
log info s"\n\n-------idList: ${idList mkString " "}"

例如,这对我有用:

val idList = List(1, 2, 3, 4, 5)
println(s"\n\n-------idList: ${idList mkString " "}")

输出:

-------idList: 1 2 3 4 5