Nim 在编译时反映类型的字段类型
Nim reflect on type's field types at compile-time
假设我有一个定义如下的类型:
type TMyStruct = object
foo: int32
bar: int16
我的目标是构建一个宏(或其他),给定一个像上面那样的 "simple" 对象类型,它能够计算该类型中每个字段的大小的总和,基于sizeof
。在这种情况下,int32
的大小为 4,int16
的大小为 2,所以想法是
myMacro(TMyStruct) # or, in the worst case, myMacro(x) where x is a TMyStruct
应该计算为 6 作为常量表达式。我想稍后将它扩展到嵌套对象,但是一旦基本版本工作,通过递归应该很容易。
我尝试了很多东西,但都失败了;我设法得到的最远的是检索 AST 中的字段名称 "foo" 和 "bar" 作为 nnkSymNodes,但我无法检索有关它们类型的任何信息。有意义的文档(以我的 Nim 专业水平)很少甚至不存在。
我问的是可能的吗,我需要使用什么 Nim 功能来实现它?
谢谢
import macros
type TMyStruct = object
foo: int32
bar: int16
macro sumSizes(t: typedesc): expr =
result = nil
let tDesc = getType(getType(t)[1])
for field in tDesc[2].children:
let sizeOfThis = newCall("sizeof", field)
if isNil(result):
result = sizeOfThis
else:
result = infix(result, "+", sizeOfThis)
echo sumSizes(TMyStruct)
有点奇怪,您必须在开头链接 getType
调用。这是因为 getType(t)
returns 以下内容:
BracketExpr
Sym "typeDesc"
Sym "TMyStruct"
如果您想对类型的实例执行此操作,只需更改以下行:
macro sumSizes(e: typed): expr =
result = nil
let tDesc = getType(e)
请注意,typed
在宏中输入符号很重要。
假设我有一个定义如下的类型:
type TMyStruct = object
foo: int32
bar: int16
我的目标是构建一个宏(或其他),给定一个像上面那样的 "simple" 对象类型,它能够计算该类型中每个字段的大小的总和,基于sizeof
。在这种情况下,int32
的大小为 4,int16
的大小为 2,所以想法是
myMacro(TMyStruct) # or, in the worst case, myMacro(x) where x is a TMyStruct
应该计算为 6 作为常量表达式。我想稍后将它扩展到嵌套对象,但是一旦基本版本工作,通过递归应该很容易。
我尝试了很多东西,但都失败了;我设法得到的最远的是检索 AST 中的字段名称 "foo" 和 "bar" 作为 nnkSymNodes,但我无法检索有关它们类型的任何信息。有意义的文档(以我的 Nim 专业水平)很少甚至不存在。
我问的是可能的吗,我需要使用什么 Nim 功能来实现它?
谢谢
import macros
type TMyStruct = object
foo: int32
bar: int16
macro sumSizes(t: typedesc): expr =
result = nil
let tDesc = getType(getType(t)[1])
for field in tDesc[2].children:
let sizeOfThis = newCall("sizeof", field)
if isNil(result):
result = sizeOfThis
else:
result = infix(result, "+", sizeOfThis)
echo sumSizes(TMyStruct)
有点奇怪,您必须在开头链接 getType
调用。这是因为 getType(t)
returns 以下内容:
BracketExpr
Sym "typeDesc"
Sym "TMyStruct"
如果您想对类型的实例执行此操作,只需更改以下行:
macro sumSizes(e: typed): expr =
result = nil
let tDesc = getType(e)
请注意,typed
在宏中输入符号很重要。