自定义标注

可以定义自定义类型的编译指示。 自定义编译指示不会直接影响代码生成,但可以通过宏检测它们的存在。 使用带有编译指示“pragma”的注释模板定义自定义编译指示:

  1. template dbTable(name: string, table_space: string = "") {.pragma.}
  2. template dbKey(name: string = "", primary_key: bool = false) {.pragma.}
  3. template dbForeignKey(t: typedesc) {.pragma.}
  4. template dbIgnore {.pragma.}

考虑风格化的对象关系映射(ORM)实现示例:

  1. const tblspace {.strdefine.} = "dev" # dev, test和prod环境的开关
  2.  
  3. type
  4. User {.dbTable("users", tblspace).} = object
  5. id {.dbKey(primary_key = true).}: int
  6. name {.dbKey"full_name".}: string
  7. is_cached {.dbIgnore.}: bool
  8. age: int
  9.  
  10. UserProfile {.dbTable("profiles", tblspace).} = object
  11. id {.dbKey(primary_key = true).}: int
  12. user_id {.dbForeignKey: User.}: int
  13. read_access: bool
  14. write_access: bool
  15. admin_acess: bool

在此示例中,自定义编译指示用于描述Nim对象如何映射到关系数据库的模式。 自定义编译指示可以包含零个或多个参数。 为了传递多个参数,请使用模板调用语法之一。 键入所有参数并遵循模板的标准重载决策规则。 因此,可以为参数,按名称传递,varargs等提供默认值。

可以在可以指定普通编译指示的所有位置使用自定义编译指示。 可以注释过程,模板,类型和变量定义,语句等。

宏模块包括帮助程序,可用于简化自定义编译器访问 hasCustomPragmagetCustomPragmaVal 。 有关详细信息,请参阅宏模块文档。 这些宏没有魔法,它们不会通过遍历AST对象表示做任何你不能做的事情。

自定义编译指示的更多示例:

  • 更好的序列化/反序列化控制:
  1. type MyObj = object
  2. a {.dontSerialize.}: int
  3. b {.defaultDeserialize: 5.}: int
  4. c {.serializationKey: "_c".}: string
  • 在游戏引擎中采用gui检查的类型:
  1. type MyComponent = object
  2. position {.editable, animatable.}: Vector3
  3. alpha {.editRange: [0.0..1.0], animatable.}: float32