我有一个nim proc,它根据第一个缩进行的空白而使用多行字符串:
import strutils
proc dedent(s: string): string
{.noSideEffect.} =
var prefix = ""
for line in s.splitLines(keepEol=true):
if prefix == "" and line.len > 0:
for j in 0..<line.len:
if line[j] != ' ':
prefix = line[0..j-1]
break
if line.startsWith(prefix):
result.add(line[prefix.len .. high(line)])
else:
result.add(line)
when isMainModule:
echo dedent """
cat:
- meow
- purr
dog:
- bark
- drool
"""
很好地输出:
cat:
- meow
- purr
dog:
- bark
- drool
但是检查中间C代码,我看到:
STRING_LITERAL(TM_9amIjLnWbK7OR9aPA8dicbaQ_14, " cat:\012 - meow\012 - purr\012 \012 "
" dog:\012 - bark\012 - drool\012 ", 112);
所以dedenting是在运行时完成的。我可以将compileTime
编译指示添加到proc:
proc dedent(s: string): string
{.noSideEffect,compileTime.} =
然后C输出变为:
STRING_LITERAL(TM_9amIjLnWbK7OR9aPA8dicbaQ_3, "cat:\012 - meow\012 - purr\012\012dog:\012 - bark\012 - drool\012", 48);
这正是我想要的,多行字符串在每行上缩进其周围,但在可执行文件中没有额外的缩进。
但是,添加该pragma,我无法再在运行时访问dedent
,例如添加时:
import os
if paramCount() > 0:
for i in 1..paramCount():
echo dedent paramStr(i)
到isMainModule
,你得到错误:
错误:请求为.compileTime proc:dedent生成代码
我查看了splitLines
中strutils.nim
的来源,看看是否还有其他一些我可以应用的编译指示,但我找不到任何有用的东西。
我现在关于static
语句,但是希望编译器在编译时优化它,而不必将其填入。
如何在不转换为使用static
的情况下使编译时和运行时都能正常工作?我是否需要从单独的.nim
模块编译proc?或者是否有编译器选项,pragma,还有其他东西,我错过了?
您需要将--implicitStatic:on
标志传递给Nim编译器,以启用对过程的隐式编译时评估。
这些程序不能有compileTime
编译指示。
要在编译时强制计算任何表达式,可以按以下方式使用static
:
when isMainModule:
echo static(dedent"""
cat:
- meow
- purr
dog:
- bark
- drool
""")
分配给常量的所有表达式也在编译时进行计算,因此这是实现相同目的的另一种方法。