理解词汇范围 - 维基百科是否正确?

时间:2018-01-09 10:10:55

标签: bash scope lexical-scope

我一直在努力克服词汇范围(我不太相信使用 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,因为函数g打印x的(动态)值然后设置x = 2的值。

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

3 个答案:

答案 0 :(得分:2)

来自内置bash的{​​{1}}手册页说明(强调我的)

  

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

调用local时,g(未标记为x)的值将从最近的运行时上下文中使用。从local调用g时,这意味着f定义的局部变量x,而不是全局变量f。这适用于x的查找分配。从全局范围调用x时,g引用全局变量x

这与词法范围形成对比,其中函数x中的x始终引用全局g,因为x已定义在全球范围内。如果函数被称为来自并不相关。

答案 1 :(得分:1)

Bash vars使用dynamic scoping,就像你提到的wiki页面一样。

  

使用动态范围的语言示例包括Logo,Emacs Lisp和shell语言 bash ,破折号和PowerShell。

     

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

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

答案 2 :(得分:0)

library(glmnet) ## Simulate data: set.seed(3) x <- data.frame( IV1 = rnorm(100), IV2 = rnorm(100), IV3 = rnorm(100), IV4 = rnorm(100), IV5 = rnorm(100) ) x <- as.matrix(x) y <- rnorm(100) #target or response ## Iteratively fit models lambdas <- NULL #initialize n.fits <- 100 for (i in 1:n.fits) { fit <- cv.glmnet(x, y, family="gaussian") df <- data.frame(fit$lambda.1se, mean(fit$cvm) ) #can use median for CVM also lambdas <- rbind(lambdas, df) } ## Select best lambda: bestindex <- which.min(lambdas[ , 2]) #the way you had it was way too complicated bestlambda <- lambdas[bestindex, 1] bestlambda 将2分配给函数g的本地x。当f结束时,他的激活记录从堆栈中弹出,然后第二个echo在堆栈中查找并找到开头的f