如何使 proc 可用编译时间和 运行 时间
how to make a proc available compile time and run time
我有一个 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:2 - meow2 - purr2 2 "
" dog:2 - bark2 - drool2 ", 112);
因此在 运行 时完成了缩进。我可以将 compileTime
pragma 添加到 proc:
proc dedent(s: string): string
{.noSideEffect,compileTime.} =
然后 C 输出变为:
STRING_LITERAL(TM_9amIjLnWbK7OR9aPA8dicbaQ_3, "cat:2 - meow2 - purr22dog:2 - bark2 - drool2", 48);
这正是我想要的,每行周围缩进的多行字符串,但在可执行文件中没有额外的缩进。
但是添加那个 pragma,我无法再在 运行 时访问 dedent
,例如添加时:
import os
if paramCount() > 0:
for i in 1..paramCount():
echo dedent paramStr(i)
到isMainModule
,你得到错误:
Error: request to generate code for .compileTime proc: dedent
我查看了 strutils.nim
中 splitLines
的源代码,看看是否有其他一些我可以应用的编译指示,但我没有找到任何有用的东西。
我现在关于 static
语句,但更希望编译器在编译时优化它,而我不必将其添加进去。
如何在不恢复使用 static
的情况下使它在编译时和 运行 时都起作用?
我需要从单独的 .nim
模块编译 proc 吗?或者是否有我缺少的编译器选项、pragma 或其他东西?
您需要将 --implicitStatic:on
标志传递给 Nim 编译器以启用程序的隐式编译时评估。
这些过程不能有compileTime
pragma。
要在编译时强制计算任何表达式,您可以按以下方式使用 static
:
when isMainModule:
echo static(dedent"""
cat:
- meow
- purr
dog:
- bark
- drool
""")
分配给常量的所有表达式也在编译时求值,因此这是实现相同目的的另一种方法。
我有一个 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:2 - meow2 - purr2 2 "
" dog:2 - bark2 - drool2 ", 112);
因此在 运行 时完成了缩进。我可以将 compileTime
pragma 添加到 proc:
proc dedent(s: string): string
{.noSideEffect,compileTime.} =
然后 C 输出变为:
STRING_LITERAL(TM_9amIjLnWbK7OR9aPA8dicbaQ_3, "cat:2 - meow2 - purr22dog:2 - bark2 - drool2", 48);
这正是我想要的,每行周围缩进的多行字符串,但在可执行文件中没有额外的缩进。
但是添加那个 pragma,我无法再在 运行 时访问 dedent
,例如添加时:
import os
if paramCount() > 0:
for i in 1..paramCount():
echo dedent paramStr(i)
到isMainModule
,你得到错误:
Error: request to generate code for .compileTime proc: dedent
我查看了 strutils.nim
中 splitLines
的源代码,看看是否有其他一些我可以应用的编译指示,但我没有找到任何有用的东西。
我现在关于 static
语句,但更希望编译器在编译时优化它,而我不必将其添加进去。
如何在不恢复使用 static
的情况下使它在编译时和 运行 时都起作用?
我需要从单独的 .nim
模块编译 proc 吗?或者是否有我缺少的编译器选项、pragma 或其他东西?
您需要将 --implicitStatic:on
标志传递给 Nim 编译器以启用程序的隐式编译时评估。
这些过程不能有compileTime
pragma。
要在编译时强制计算任何表达式,您可以按以下方式使用 static
:
when isMainModule:
echo static(dedent"""
cat:
- meow
- purr
dog:
- bark
- drool
""")
分配给常量的所有表达式也在编译时求值,因此这是实现相同目的的另一种方法。