如何使proc可用编译时和运行时

问题描述 投票:1回答:2

我有一个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生成代码

我查看了splitLinesstrutils.nim的来源,看看是否还有其他一些我可以应用的编译指示,但我找不到任何有用的东西。

我现在关于static语句,但是希望编译器在编译时优化它,而不必将其填入。

如何在不转换为使用static的情况下使编译时和运行时都能正常工作?我是否需要从单独的.nim模块编译proc?或者是否有编译器选项,pragma,还有其他东西,我错过了?

compile-time nim multilinestring
2个回答
1
投票

您需要将--implicitStatic:on标志传递给Nim编译器,以启用对过程的隐式编译时评估。

这些程序不能有compileTime编译指示。


1
投票

要在编译时强制计算任何表达式,可以按以下方式使用static

when isMainModule:
    echo static(dedent"""
        cat:
          - meow
          - purr

        dog:
          - bark
          - drool
        """)

分配给常量的所有表达式也在编译时进行计算,因此这是实现相同目的的另一种方法。

© www.soinside.com 2019 - 2024. All rights reserved.