我有一个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);
因此,缩排在运行时完成。我可以将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);
这正是我想要的,多行字符串缩进到每行的周围,但在可执行文件中没有多余的缩进。
但是添加了这个实用性,我无法再在运行时访问dedent
,例如添加时:
import os
if paramCount() > 0:
for i in 1..paramCount():
echo dedent paramStr(i)
到isMainModule
,您会收到错误消息:
错误:请求为.compileTime过程生成代码proc:ddent
我在splitLines
中查看了strutils.nim
的来源,以了解是否还有其他我可以应用的语用说明,但是我没有找到任何可行的方法。
我现在谈论static
语句,但希望编译器在编译时对其进行优化,而无需我将其投入其中。
如何在不恢复使用static
的情况下使它既在编译时又在运行时工作?
我是否需要从单独的.nim
模块编译proc?还是我缺少一个编译器选项,杂注或其他?
答案 0 :(得分:1)
您需要将--implicitStatic:on
标志传递给Nim编译器以启用对过程的隐式编译时评估。
这些过程不能具有compileTime
编译指示。
答案 1 :(得分:1)
要在编译时强制对任何表达式求值,可以通过以下方式使用static
:
when isMainModule:
echo static(dedent"""
cat:
- meow
- purr
dog:
- bark
- drool
""")
所有分配给常量的表达式也在编译时求值,因此这是另一种实现方法。