如何在 Nim 的格式化字符串中使用表达式?
How can I use expression inside formatted string in Nim?
如果在 fmt
字符串中使用,if
表达式将不起作用。
为什么,以及如何让它发挥作用?
import strformat
let v = if true: 1 else: 2 # <= Works
echo fmt"{v}"
echo fmt"{if true: 1 else: 2}" # <= Error
为什么?
因为 fmt
使用 :
将表达式的值与格式说明符分开,所以(参见 docs and implementation)行
echo fmt"{if true: 1 else: 2}"
被宏扩展为
var temp = newStringOfCap(educatedCapGuess)
temp.formatValue if true, " 1 else: 2"
temp
显然无法编译。
如何?
更新
目前(2021 年 4 月)在 devel 分支中有一个增强功能,允许在格式化字符串中使用任何表达式。对于提到的特定情况,您需要用括号将表达式括起来:
echo fmt"{(if true: 1 else: 2)}"
新的增强功能还允许在表达式中使用大括号(转义)。
参见:
- RFC:https://github.com/nim-lang/RFCs/issues/366
- 一个 first and a second 添加了实现的 PR
- 最近的论坛讨论:https://forum.nim-lang.org/t/7052
此增强功能将在下一个稳定版本(可能是 1.6)中针对一般 public 发布。
旧内容
我猜它可以被视为 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。
如果在 fmt
字符串中使用,if
表达式将不起作用。
为什么,以及如何让它发挥作用?
import strformat
let v = if true: 1 else: 2 # <= Works
echo fmt"{v}"
echo fmt"{if true: 1 else: 2}" # <= Error
为什么?
因为 fmt
使用 :
将表达式的值与格式说明符分开,所以(参见 docs and implementation)行
echo fmt"{if true: 1 else: 2}"
被宏扩展为
var temp = newStringOfCap(educatedCapGuess)
temp.formatValue if true, " 1 else: 2"
temp
显然无法编译。
如何?
更新
目前(2021 年 4 月)在 devel 分支中有一个增强功能,允许在格式化字符串中使用任何表达式。对于提到的特定情况,您需要用括号将表达式括起来:
echo fmt"{(if true: 1 else: 2)}"
新的增强功能还允许在表达式中使用大括号(转义)。
参见:
- RFC:https://github.com/nim-lang/RFCs/issues/366
- 一个 first and a second 添加了实现的 PR
- 最近的论坛讨论:https://forum.nim-lang.org/t/7052
此增强功能将在下一个稳定版本(可能是 1.6)中针对一般 public 发布。
旧内容
我猜它可以被视为 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。