名字解析 (程序设计)

计算机程序设计语言中，名字解析是指把程序表达式中的标记（）对应解析到程序成分（）。

概述
不同语言的名字解析算法的复杂度不同。例如，汇编语言的名字解析只需要简单地查。而C++的名字解析就非常复杂，受命名空间、作用域、可见性规则（）、函数重载、可访问性（）影响。

静态解析与动态解析
编译时完成的称静态名字解析；运行时完成的称动态名字解析。

动态类型并不意味着动态名字解析。例如，Erlang是动态类型但静态名字解析。

下述Python程序:
>>> locals()['num'] = 999 # equivalent to: num = 999
>>> noun = "troubles"
>>> noun2 = "hound"
>>> # which variables to use are decided at runtime
>>> print("{num} {noun} and a {noun2} ain't one".format(**locals()))
999 troubles and a hound ain't one
但现在的编程风格指引不建议使用动态名字解析。

静态名字解析的语言有：C语言, C++, E语言, Erlang, Haskell, Java, Pascal语言, Scheme语言, Smalltalk。动态名字解析的语言有：Lisp, Perl, PHP, Python, REBOL, Tcl.

名字屏蔽
名字屏蔽（）发生在同一个名字用于不同的实体，出现在重叠的作用域内。 例如，在下述程序中：
  private int foo;  // A declaration with name "foo" in an outer scope
  public void setFoo(int foo) {  // A declaration with the same name in the inner scope
    // "foo" is resolved by looking in the innermost scope first,
    // so the author uses a different syntax, this.foo, to refer to the name "foo"
    // in the outer scope.
    this.foo = foo;
  }
  // "foo" here means the same as this.foo below,
  // since setFoo's parameter is no longer in scope.
  public int getFoo() { return foo; }

α更名简化了名字解析
程序设计语言使用α-变换使得没有变量名屏蔽了其它同名的实体。可用于静态代码分析，使得理解源代码更为容易。

例如：
  class Point {
  private:
    double x, y;

  public:
    Point(double x, double y) {  // x and y declared here mask the privates
      setX(x);
      setY(y);
    }

    void setX(double newx) { x = newx; }
    void setY(double newy) { y = newy; }
  }
Point构造函数中，类的数据成员x与y被局部变量屏蔽了。这可通过α更名改善：
  class Point {
  private:
    double x, y;

  public:
    Point(double a, double b) {
      setX(a);
      setY(b);
    }

    void setX(double newx) { x = newx; }
    void setY(double newy) { y = newy; }
  }

参见
 命名空间
 作用域


参考文献

Category:编译原理
Category:计算机编程