方法调用语法限制

x.f 中的表达式 x 需要进行语义检查(即符号查找和类型检查),然后才能确定需要将其重写为 f(x) 。 因此,当用于调用模板/宏时,点语法有一些限制:

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

另一个常见的例子是:

  1. from sequtils import toSeq
  2.  
  3. iterator something: string =
  4. yield "Hello"
  5. yield "World"
  6.  
  7. var info = something().toSeq

这里的问题是编译器已经决定 something() 作为迭代器在 toSeq 将其转换为序列之前不可调用。

It is also not possible to use fully qualified identifiers with module symbol in method call syntax. The order in which the dot operator binds to symbols prohibits this.

  1. import sequtils
  2.  
  3. var myItems = @[1,3,3,7]
  4. let N1 = count(myItems, 3) # OK
  5. let N2 = sequtils.count(myItems, 3) # fully qualified, OK
  6. let N3 = myItems.count(3) # OK
  7. let N4 = myItems.sequtils.count(3) # illegal, `myItems.sequtils` can't be resolved

This means that when for some reason a procedure needs a disambiguation through the module name, the call needs to be written in function call syntax.