我一直在努力克服词汇范围(我不太相信使用 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的值。
我是否需要更正维基百科条目,或调整我的理解?
答案 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
。