【问题标题】:Nim enum converter macro?Nim枚举转换器宏?
【发布时间】:2021-08-14 04:13:31
【问题描述】:

为什么这个字符串到枚举转换器宏无法编译? play

import std/macros, std/strutils

macro autoconvert(TT: type[enum]) =
  let fname = "to" & $(TT)
  quote do:
    converter `fname`*(s: string): `TT` = parse_enum[`TT`](s)

type Tag* = enum movies, books
autoconvert Tag

错误

play.nim(12, 13) template/generic instantiation of `autoconvert` from here
play.nim(7, 3) Error: identifier expected, but found '"toTag"'

更新:

解决方案是使用ident "to" & $(TT),但为什么它不适用于字符串或newLit

【问题讨论】:

  • fname 需要是一个 NimNode(正确的类型),因为宏返回 AST,而不是字符串,并且因为 quote 在反引号内替换了 NimNode。

标签: nim-lang


【解决方案1】:

您使用字符串文字作为过程名称而不是标识符 ident("to" & $(TT)) 解决了这个问题,但您也使用宏而不是模板。它不适用于 lit 的原因是文字是 "toTag" 而标识符是 toTag。我建议查看结果的treeReprrepr,看看发生了什么。以下为上述模板方式。

import std/strutils

template autoConvert*(TT: type[enum]) {.dirty.} =
    converter toTag*(s: string): TT = parse_enum[TT](s)

type Tag* = enum movies, books
autoconvert Tag

【讨论】:

  • 谢谢!还有一个问题,您知道是否可以将其用作编译指示type Tag* {.autoconvert.} = enum movies, books
  • 不,目前 typdef 宏只能获取该 typedef 的主体,不能在其外部发出代码,因此您只能修改类型而不能添加过程。
  • 可以使用 nnkStmtListType 将过程添加到宏中的类型
猜你喜欢
  • 2023-01-03
  • 2018-06-15
  • 2017-10-14
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-23
相关资源
最近更新 更多