String 字符串插值

String 字符串插值,string,string-interpolation,nim-lang,nimrod,String,String Interpolation,Nim Lang,Nimrod,在scala中,您可以轻松地将变量的内容包含在字符串中,如下所示: val nm = "Arrr" println(s"my name is , $nm") 这在nim中可能吗?在这种情况下,如何实现?一些实验性功能: 添加您自己的,因为标准库已经提供了大多数必需的部分: import macros, parseutils, sequtils macro i(text: string{lit}): expr = var nodes: seq[PNimrodNode] = @[] #

在scala中,您可以轻松地将变量的内容包含在字符串中,如下所示:

val nm = "Arrr"
println(s"my name is , $nm")
这在nim中可能吗?在这种情况下,如何实现?

一些实验性功能:

添加您自己的,因为标准库已经提供了大多数必需的部分:

import macros, parseutils, sequtils

macro i(text: string{lit}): expr =
  var nodes: seq[PNimrodNode] = @[]
  # Parse string literal into "stuff".
  for k, v in text.strVal.interpolatedFragments:
    if k == ikStr or k == ikDollar:
      nodes.add(newLit(v))
    else:
      nodes.add(parseExpr("$(" & v & ")"))
  # Fold individual nodes into a statement list.
  result = newNimNode(nnkStmtList).add(
    foldr(nodes, a.infix("&", b)))

const
  multiplier = 3
  message = i"$multiplier times 2.5 is ${multiplier * 2.5}"

echo message
# --> 3 times 2.5 is 7.5

proc blurb(a: int): string =
  result = i"param a ($a) is not a constant"

when isMainModule:
  for f in 1..10:
    echo f.blurb
现在,这被认为是实现这一目标的必经之路:

import strformat
let nm = "Arrr"
echo fmt"my name is , {nm}"

太棒了,这真的应该包括在标准库中。我同意bluenote10。谢谢,这是一个很好的定制解决方案。如果没有在编译时初始化变量,它能工作吗?应该提到,
interpolatedFragments
将在类似
“${a&”}的情况下中断“&b}
,因为它只计算大括号
strfmt
目前也存在这种问题,但应该有一种方法来解决它,方法是将
interpolatedFragments
制作成
compileTime
迭代器,允许使用
parseExpr
来正确解析表达式。@arrrrrr为什么不呢?宏对变量不做任何处理,它只转换文本以将其分解为串联。在示例中添加了一些“运行时”行。@bluenote10
interpolatedFragments
非常简单,不适用于嵌套大括号。没有什么能阻止您在解析循环内实现一个支撑机制,并使之与SQL分析器类似。但在这一点上,我想说你滥用字符串插值没有什么好处。@GrzegorzAdamHankiewicz:我想说的是,由于宏是在编译时扩展的,编译器的全部功能无论如何都是可用的,使用它的表达式解析器(如果可能的话!)而不是手动解析它是有意义的。我认为,允许任何可能的语言语句都不是一种滥用,就像Scala中一样。限制的问题不在于限制过多,而是人们不知道这些限制,他们会浪费时间找出为什么会出现奇怪的编译错误。
import strformat
let nm = "Arrr"
echo fmt"my name is , {nm}"