【问题标题】:Understanding lexical scoping - is Wikipedia correct?理解词法作用域——维基百科正确吗?
【发布时间】:2018-01-09 10:10:54
【问题描述】:

我一直在尝试理解词法作用域(我对 lexical 这个词的使用远非信服,但这是另一个讨论),我查看了 Wikipedia's entry

根据相当简单的 Bash 脚本示例

$ x=1 
$ function g () { echo $x ; x=2 ; }
$ function f () { local x=3 ; g ; }
$ f # does this print 1, or 3?
3
$ echo $x # does this print 1, or 2?
1

Bash 脚本的输出是 3, 1。但是,在我看来,它应该是 3, 2,因为函数 g 打印 x 的(动态)值,然后设置 x = 2 的值。

我需要更正维基百科条目,还是调整我的理解?

【问题讨论】:

  • 它将f中的本地var设置为2,当f结束时,var被binned。把echo $x放在g;之后
  • 谢谢。这对我来说很清楚。

标签: bash scope lexical-scope


【解决方案1】:

Bash 变量使用 dynamic scoping,就像您提到的 wiki 页面中一样。

使用动态范围的语言示例包括 Logo、Emacs Lisp 和 shell 语言 bash、dash 和 PowerShell。

动态范围很容易实现。 为了找到标识符的值,程序可以遍历运行时堆栈,检查每个激活记录(每个函数的堆栈帧)中的标识符值。

有关如何使用它,请参阅Bash: Passing variables by reference

【讨论】:

    【解决方案2】:

    来自bash 内置的local 手册页描述(重点是我的)

    当在函数中使用 local 时,它会导致 变量名的可见范围仅限于该函数及其子函数

    g 被调用时,x 的值(未标记为local)从最近的封闭 runtime 上下文中使用。当gf调用时,是指f定义的局部变量x,而不是全局变量x。这适用于x 的查找分配。当从全局作用域调用g时,x指的是全局变量x

    这与词法作用域形成对比,其中函数g 中的x 将始终引用全局x,因为g 在全局作用域中定义from 调用函数的位置不相关。

    【讨论】:

    • 抱歉打扰了。我希望可以问。 :) 我坐在一个几乎不使用动态作用域的 shell 程序前面,主要是在函数之间传递数组。变量用于不同的函数和函数组合,这些函数分布在五个源文件中。在我看来,这段代码的可读性/可遵循性较差,并且函数紧密耦合的事实使其容易出现错误并且难以维护。你会说这只是 shell 代码的正常做法,我不得不期待,还是你同意?
    【解决方案3】:

    g 将 2 分配给函数 f 的本地 x。当f结束时,他的激活记录从栈中弹出,然后第二个echo在栈中查找,找到开始的x = 1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-12
      • 2011-04-22
      • 1970-01-01
      • 2014-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多