我正在阅读使用R的动手编程,他在一个典范中创建以下功能:
setup <- function(deck){
DECK <- deck
DEAL <- function(){
card <- deck[1,]
assign("deck",deck[-1,],envir = parent.env(environment()))
card
}
SHUFFLE <- function(){
random <- sample(1:52,52)
assign("deck",DECK[random,],envir = parent.env(environment()))
}
list(deal=DEAL, shuffle=SHUFFLE)
}
cards <- setup(deck)
deal <- cards$deal
shuffle <- cards$shuffle
甲板在这里。
首次致电deal
时,所示的环境为<environment: 0x9eea314>
。然后,我开始处理该函数deal()
,我发现,如果我再次调用setup(deck)
,则交易函数将被重置。我这样做了,deal
的环境正在更改为<environment: 0xad77a60>
,但是当我与deal()
打交道时,我感到惊讶。我叫deal
,我发现实际上环境没有改变。
发生了什么事?当我第一次设置交易功能时,无论我称之为 setup(deck)
多少次,它不会更改或我创建其他函数在范围未达到的不同环境中交易?
我认为问题是您要查看的"甲板"是cards
-Object中的"甲板"。shuffle()
之后,我们可以看到此行为:
> deal()
face suit value
17 ten clubs 10
> str(deck)
'data.frame': 52 obs. of 3 variables:
$ face : Factor w/ 13 levels "ace","eight",..: 6 8 5 11 7 2 9 10 3 4 ...
$ suit : Factor w/ 4 levels "clubs","diamonds",..: 4 4 4 4 4 4 4 4 4 4 ...
$ value: int 13 12 11 10 9 8 7 6 5 4 ...
所以我确实看到你的困惑。我像您一样,期望在甲板上看到51张卡片,我期望随机订购卡值和西装(我们也看不到(,但让我们继续...
> deal()
face suit value
37 three diamonds 3
> deal()
face suit value
23 four clubs 4
> str(cards)
现在,让我们尝试找到由shuffle
和deal
函数操纵的"真实" deck
-Object,它显然与globalenv()
中保持不变的deck
对象不同。R功能实际上是关闭,这是代码和封闭环境的组合。考虑到这一点,让我们检查cards
:
> str(cards)
List of 2
$ deal :function ()
..- attr(*, "srcref")=Class 'srcref' atomic [1:8] 4 15 8 7 15 7 4 8
.. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x7f84081d3780>
$ shuffle:function ()
..- attr(*, "srcref")=Class 'srcref' atomic [1:8] 10 18 13 7 18 7 10 13
.. .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x7f84081d3780>
现在检查cards
中的第一个功能的环境:
> ls(env=environment(cards[[1]]))
[1] "DEAL" "deck" "DECK" "SHUFFLE"
现在看一下该环境中"甲板"的价值:
str(environment(cards[[1]])$deck)
'data.frame': 49 obs. of 3 variables:
$ face : Factor w/ 13 levels "ace","eight",..: 4 1 13 7 11 13 8 2 2 3 ...
$ suit : Factor w/ 4 levels "clubs","diamonds",..: 4 1 4 1 3 3 4 3 4 1 ...
$ value: int 4 1 2 9 10 2 12 8 8 5 ...
因此,我认为我们已经找到了我们应该研究的实际"甲板" - 对象(因为它具有正确的数字和随机订购(,并且它不是globalenv()
中仍在(不变的(。此外,共享这两个功能的环境:
environment(cards[[2]])
#<environment: 0x7f84081702a8>
environment(cards[[1]])
#<environment: 0x7f84081702a8>
...但是,我认为游戏"语义"可能存在问题,如果shuffle
在游戏中意外执行:
> shuffle()
> str(environment(cards[[2]])$deck)
'data.frame': 52 obs. of 3 variables:
$ face : Factor w/ 13 levels "ace","eight",..: 11 9 2 7 8 1 7 3 5 13 ...
$ suit : Factor w/ 4 levels "clubs","diamonds",..: 2 3 4 4 2 4 3 4 3 3 ...
$ value: int 10 7 8 9 12 1 9 5 11 2 ...