方法调用语法的局限

x.f 里的表达式 x 需要先经过语义检查(意味着符号查找和类型检查),然后才能决定是否需要重写成 f(x) 的形式。因此,当用于调用模板或宏时,. 语法有一些局限:

  1. template declareVar(name: untyped) =
  2. const name {.inject.} = 45
  3. # 无法编译:
  4. unknownIdentifier.declareVar

在方法调用语义中,无法使用带有模块符号的完全限定标识符,这是 . 运算符的绑定顺序决定的。

  1. import std/sequtils
  2. var myItems = @[1,3,3,7]
  3. let N1 = count(myItems, 3) # 可行
  4. let N2 = sequtils.count(myItems, 3) # 完全限定, 此处可行
  5. let N3 = myItems.count(3) # 可行
  6. let N4 = myItems.sequtils.count(3) # 非法的, `myItems.sequtils` 无法解析

这就是说,当由于某种原因,一个过程需要借助模块名消除歧义时,这个调用就需要使用函数调用的语法来书写。