问题描述
如果在if
字符串中使用fmt
表达式,则不起作用。
为什么以及如何使其工作?
import strformat
let v = if true: 1 else: 2 # <= Works
echo fmt"{v}"
echo fmt"{if true: 1 else: 2}" # <= Error
解决方法
为什么?
因为fmt
使用:
来将表达式的值与格式说明符分开,所以(请参见docs和implementation)该行
echo fmt"{if true: 1 else: 2}"
被宏扩展为
var temp = newStringOfCap(educatedCapGuess)
temp.formatValue if true," 1 else: 2"
temp
显然无法编译。
如何?
我想这可以看作是fmt
的局限性,而且我认为目前还没有一种方法可以在:
中将表达式与fmt
一起使用,而该表达式不能用作格式更规范。
解决此问题的一种方法是提供一个额外的formatSpecifierSeparator
关键字参数,以更改默认的:
并能够执行以下操作:
echo "{if true: 1 else: 2}".fmt('|')
另一种方法是更改strformatImpl
的实现,并在将:
解释为formatSpecifier分隔符之前,确保:
之前的部分实际上已编译。
这两种方式均暗含着nim-lang代码的PR,如果被接受并合并,则可以在下一个发行版或之后的版本中获得。
,这有效:
import std/strformat
let x = 3.14
assert fmt"{(if x!=0: 1.0/x else: 0):.5}" == "0.31847"
assert fmt"{(if true: 1 else: 2)}" == "1"
assert fmt"{if true\: 1 else\: 2}" == "1"
并避免与格式说明符冲突。有关详情,请参阅 https://github.com/nim-lang/Nim/pull/17700。